Jump to content

Recommended Posts

REPLACE NON-DIGITS (except "X") WITH COMMA,
THEN GET RID OF MULTIPLE COMMAS

From this:
$string =  11111X  ,,,  ,222X ,   abcd ,,,,,,,33333X
To this:
$fixed = 11111X,222X,33333X

I gave myself 2 days to come up with a one-liner. This is the best I could do. What am I doing wrong?
 

$fixed = preg_replace("/[^\dX]|,+/",",",$string);

(of course I know how to make it happen with a bunch more code, but there's gotta be a simple one-liner 😀 )
 

There's an easier approach if you think about it in a slightly different way.

You want to replace non-digits (besides X) with a comma. If there are multiple consecutive non-digits then they'll be replaced with multiple consecutive commas.
You also want to replace multiple consecutive commas with one single comma.

Do you see the repetition in there? Multiple non-digits become multiple commas become one comma. You could skip that whole middle step and go straight from multiple non-digits to a single comma.

Then what about multiple commas. Well, a comma counts as a "non-digit", doesn't it?

10 hours ago, requinix said:

if you think about it in a slightly different way

No no no! As I said already, I want a "one-liner."
 

10 hours ago, requinix said:

You want to replace non-digits...

You sound like one of those Tech Support agents who repeat your entire question back to you ad nauseum.
As I said already, I have been working on this for TWO days, do you not think that I have thought this through?

10 hours ago, requinix said:

then what about multiple commas. Well, a comma counts as a "non-digit", doesn't it?

Again, already thought this through. I know can make this work with simple String Manipulation, I can do str_replace, etc.,

In fact, I can simply leave the commas out of my practice regex problem to begin with. Then, problem solved.

I am trying to learn RegEx!

So look, if I have preg_replace("/[^\d]/",",",'100 horses') the [^\d] replaces everything except digits with commas.
If I change that to [^\d\s]/ now it replaces everthing except digits and spaces with commas.
MY QUESTION IS: can I tweak "/[^\d]\,+/" to make it replace the multiple commas with a single comma without a nested preg_replace or string operation or other "would you like fries with that?"

Thank you.
Bless your mind.
 

Edited by ChenXiu

The answer is yes. It's a one-liner. It's crazy simple too. And I think that you can figure it out for yourself if only you were willing to think about what it is you're trying to do using a different mindset.
Because contrary to what you might think, this is not tech support. This is a learning experience. If you're willing to make use of it.

You start with a string "11111X  ,,,  ,222X ,   abcd ,,,,,,,33333X".

You care about non-digits and non-Xs, which means [^\dX]. That also includes commas too. If you replace each [^\dX] with a comma you get

"11111X,,,,,,,,222X,,,,,abcd,,,,,,,,33333X"

Now you have a bunch of commas.
What's not obvious there is that the regex also replaced each comma with another comma. No change, of course, but the important part is that the very simple [^\dX] is already looking at them.

You now think "damn, I have a lot of commas, I need to condense them all down to just one". If you did another separate regex to substitute ,+ into , then that would definitely take care of it, but here's the thing: (a) your original [^\dX] was already looking at the commas and (b) your own regex was producing some of those commas that you don't actually want. Sure doesn't make sense to use a second regex when (a) yours is already processing those bad commas and (b) it's outputting stuff you don't even like.

Still remember how [^\dX] includes commas? If you're turning [^\dX] into , and you want to replace ,+ with , then you could simply combine those together to do both actions at the same time. Right? Which results in replacing [^\dX]+ with ,

But what will that do on the input string?
1. "11111X" is good and gets skipped over
2. "  ,,,  ," is all matched by [^\dX]+ and gets replaced with a single comma
3. "222X" is also good and skipped over
4. " ,   abcd ,,,,,,," is all matched too and gets replaced with a single comma
5. "33333X" is good and skipped

That leaves you with "11111X" + one comma + "222X" + one comma + "33333X".

... I finished reading. The [^\dX]+ is indeed very graceful, like a slinky dress. Very svelte. Exactly what I was hoping for.
I'm disappointed that I didn't think of it or try it. There's no way I could have ever figured that out. In fact I won't even use it, it will make me mad every time I see it.
I am starting to think PHP is like music, or genetics; your either born to be a Beethovin, or stuck for the rest of your life making Elevator music.
Why couldn't I have figured that out!?
Certainly not for lack of trying.
... Maybe I could have figured it out.
Probably not.
...You should have made me try harder.

Edited by ChenXiu
  • Like 1

You were frustrated. I knew you could get the answer on your own with a little prodding, but if I didn't prod hard enough then you might just get upset at me stringing you along. So I figured a long post you had to read through that explained, but yes ultimately gave away (kinda), the answer was a decent middle-ground.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.