3

I'm feeling very silly for not being able to figure this one out, but I just cant figure it. I need to replace a regex string with a pattern, I found two examples of doing it, but they honestly left me more confused than ever.

This is my current attempt:

$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 ';
$pattern = '["SIP/CL/\d*?,\d*?",]';
$replacement = '"SIP/CL/\1|\2",';
$string = preg_replace($pattern, $replacement, $string);
print($string);

But that just replaces the \1 and \2 with blanks. So obviously I'm not getting the entire concept.

What I'm wanting at the end is to change:

this: "SIP/CL/61436523277,45"
to: "SIP/CL/61436523277|45"

That comma in a poorly formatted CSV throws off some of my other scripts.

3
  • 1
    It doesn't seem poorly formatted, as it is between quotes... You DO use fgetcsv for this, are you not? Or str_getcsv if it is a string. Commented Jan 18, 2012 at 0:21
  • I wasn't, but i am now. I needed to learn this form of regex replacement anyway. So killed two birds with one stone :). I was aware of fgetcsv, but it didn't suit my purposes (its a 1.8GB+ csv...., cant load it all in mem), but str_getcsv worked well! :) Commented Jan 18, 2012 at 0:45
  • OK, for future reference: fgetcsv doesn't read a total file into memory either, just line by line ;) Commented Jan 18, 2012 at 0:47

4 Answers 4

2

You're missing braces, the pattern should look like this:

$pattern = '["SIP/CL/(\d*),(\d*)",]';
Sign up to request clarification or add additional context in comments.

5 Comments

That was it? I feel like such a foo'. Thank you so much :) That worked perfectly.
you have changed the meaning of the non-gready operator by having outside the bracket. It shoud be (\d+?)
@user1130968 marking the most useful answer as answer is best way of saying thanks here .) (so does FAQ say)
@meouw you're right, I didn't notice that I just added braces I wouldn't use it at all
The final looked like $pattern = '["SIP/CL/(\d*),(\d*)",]'; $replacement = '"SIP/CL/\1|\2,"';
2

The backreferences \1 and \2 in your $replacement are meant to refer to captured groups in $pattern. Captured groups are saved by placing brackets around them ().

Try (I changed your regex delimiters [] to ! pending an answer from comments below):

$pattern = '!"SIP/CL/(\d*?),(\d*?)",!';
$replacement = '"SIP/CL/\1|\2",';

Also note that since you have a trailing comma on your $pattern, if your $string ended in "SIP/CL/61436523277,45" that would not be converted. I'd recommend removing that trailing comma.

Also your current regex will convert "SIP/CL/," to "SIP/CL/|". If that is not your intent, change the * after the \d (ie 0 or more matches) to a + (one or more matches).

4 Comments

[ and ] will be taken as delimeters in this case, not a character class
would not pattern 1 be SIP/CL/{numbershere} So should you want '"SIP/CL/(\d*?),(\d*?)",' or else your first reference is funny. As in your replacement would be SIP/CL/SIP/CL/numbershere|numbersagain
@meouw, I forgot about that, cheers. but then shouldn't it be [ and [ or ] and ] but not [ and ]?
PHP, like Perl, recognizes correctly-paired brackets as delimiters, so [], (), {} and <> all work. I think it's a bad idea to use them in PHP though; it's confusing enough that, unlike in Perl, you have to use regex delimiters in addition to quotes. At the least, anyone looking at your code is going to wonder if you understand why it's valid. ;)
2

I think you need this:

$pattern = '["SIP/CL/(\d+),(\d+)",]';

The parens - () - capture the match inside, allowing you to reference it in your replacement pattern.

You could also simplify the replacement pattern by expanding the captures in the match pattern:

$pattern = '[("SIP/CL/\d+),(\d+",)]';   
$replacement = '\1|\2';

Comments

0

I did this

$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 ';
$pattern = '/SIP\/CL\/([0-9]+),([0-9]+)/';
$replacement = 'SIP/CL/\1|\2';
$string = preg_replace($pattern, $replacement, $string);
print($string);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.