Vinze Posted December 24, 2006 Share Posted December 24, 2006 Hey, I got a variable $code and I want to replace all single-quoted strings (within ' and ') with _|_|_|_. I use the following pattern, but somehow it doesn't work:[code][\'(.*?)\'][/code]Why not? Quote Link to comment Share on other sites More sharing options...
wildteen88 Posted December 24, 2006 Share Posted December 24, 2006 Like this:[code=php:0]$str = "this is a 'string' which is made up of 'characters'";echo preg_replace("/'(.*?)'/", '_|_|_|_', $str);[/code] Quote Link to comment Share on other sites More sharing options...
Vinze Posted December 24, 2006 Author Share Posted December 24, 2006 [quote author=wildteen88 link=topic=119821.msg491081#msg491081 date=1166974426]Like this:[code=php:0]$str = "this is a 'string' which is made up of 'characters'";echo preg_replace("/'(.*?)'/", '_|_|_|_', $str);[/code][/quote]Yeah that's exactly what I did:[code=php:0]$i = 0;$pattern = '[\'(.*?)\']';while(preg_match($pattern, $parsed)){ $s_quotes[$i] = preg_replace($pattern, '$1', $parsed, 1);}[/code]But somehow there are totally other values than the strings in $s_quotes, so I must be doing something wrong Quote Link to comment Share on other sites More sharing options...
c4onastick Posted December 31, 2006 Share Posted December 31, 2006 In regex speak, there's a huge difference between this, a character class (part of a regex):[code][\'(.*?)\'][/code]And this, a full regex:[code]/'(.*?)'/[/code]You are right (maybe inadvertently) though, PHP's PCRE does allow you to choose your own delimiter, but (and I may be mistaken here) I don't believe you can use the square brackets '[]' as delimeters. In regex, anything in the square brackets is a character class. So to the regex engine,[code][\'(.*?)\'][/code]Says "match one (1) character from the class", so in this case one of '.', ')', or '?'... etc. Backslashes are use for metacharacters that mean special things like new line (\n), tabs (\t), etc. I'll bet that PHP is complaining about two things here.One, it doesn't know what metacharacter " \' " is. Two, you only have it matching one character, if you don't have '.' or '?' or whatever in the string I'd expect it to fail. wildteen88's solution works great. If you want to store the pattern in a variable (I see this everywhere, I don't know why people always want to do it) store it like this:[code]$pattern = "/'.*?'/";[/code]You may want to add the 's' modifier in case you have quoted strings spanning multiple lines.I (just my opinion/way of doing it) would do something like this:[code]$str = "this is a 'string' which is made up of 'characters'";echo preg_replace("/'[^']+'/", '_|_|_|_', $str);[/code]I've gotten into trouble occasionally using '.*?' too much. Although wildteen88's solution works great too. Quote Link to comment Share on other sites More sharing options...
Vinze Posted December 31, 2006 Author Share Posted December 31, 2006 [quote author=c4onastick link=topic=119821.msg494254#msg494254 date=1167584322]In regex speak, there's a huge difference between this, a character class (part of a regex):[code][\'(.*?)\'][/code]And this, a full regex:[code]/'(.*?)'/[/code]You are right (maybe inadvertently) though, PHP's PCRE does allow you to choose your own delimiter, but (and I may be mistaken here) I don't believe you can use the square brackets '[]' as delimeters. In regex, anything in the square brackets is a character class. So to the regex engine,[code][\'(.*?)\'][/code]Says "match one (1) character from the class", so in this case one of '.', ')', or '?'... etc. Backslashes are use for metacharacters that mean special things like new line (\n), tabs (\t), etc. I'll bet that PHP is complaining about two things here.One, it doesn't know what metacharacter " \' " is. Two, you only have it matching one character, if you don't have '.' or '?' or whatever in the string I'd expect it to fail. wildteen88's solution works great. If you want to store the pattern in a variable (I see this everywhere, I don't know why people always want to do it) store it like this:[code]$pattern = "/'.*?'/";[/code]You may want to add the 's' modifier in case you have quoted strings spanning multiple lines.I (just my opinion/way of doing it) would do something like this:[code]$str = "this is a 'string' which is made up of 'characters'";echo preg_replace("/'[^']+'/", '_|_|_|_', $str);[/code]I've gotten into trouble occasionally using '.*?' too much. Although wildteen88's solution works great too.[/quote][ and ] work great at all my other regular expressions, so they cannot be the problem. Also, I defined the pattern within ' and ', that's why I added the backslashes (so they will be parsed for the regex as a normal ').But I'm starting to think the problem is somewhere in $str which is a bunch of PHP code that needs to be automatically cleaned up. Quote Link to comment Share on other sites More sharing options...
c4onastick Posted January 1, 2007 Share Posted January 1, 2007 [quote author=Vinze link=topic=119821.msg494258#msg494258 date=1167584757][ and ] work great at all my other regular expressions, so they cannot be the problem. Also, I defined the pattern within ' and ', that's why I added the backslashes (so they will be parsed for the regex as a normal ').But I'm starting to think the problem is somewhere in $str which is a bunch of PHP code that needs to be automatically cleaned up.[/quote]Good to know, I wondered about that, I've never used [ and ] for anything other than character classes, I learned something today! With out seeing some of the code that's going into $str, really the only thing I would suggest is to add the 's' modifier to your pattern so that the dot picks up newlines too. Is the error that preg_replace throws any help? Or is there just no match? Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 1, 2007 Author Share Posted January 1, 2007 [quote author=c4onastick link=topic=119821.msg494493#msg494493 date=1167622794][quote author=Vinze link=topic=119821.msg494258#msg494258 date=1167584757][ and ] work great at all my other regular expressions, so they cannot be the problem. Also, I defined the pattern within ' and ', that's why I added the backslashes (so they will be parsed for the regex as a normal ').But I'm starting to think the problem is somewhere in $str which is a bunch of PHP code that needs to be automatically cleaned up.[/quote]Good to know, I wondered about that, I've never used [ and ] for anything other than character classes, I learned something today! With out seeing some of the code that's going into $str, really the only thing I would suggest is to add the 's' modifier to your pattern so that the dot picks up newlines too. Is the error that preg_replace throws any help? Or is there just no match?[/quote]The "s" modifier did not help unfortunately. I haven't looked at it yet but there is no error message, just no match. Quote Link to comment Share on other sites More sharing options...
effigy Posted January 2, 2007 Share Posted January 2, 2007 [quote author=Vinze link=topic=119821.msg491082#msg491082 date=1166974786]Yeah that's exactly what I did:[code=php:0]$i = 0;$pattern = '[\'(.*?)\']';while(preg_match($pattern, $parsed)){ $s_quotes[$i] = preg_replace($pattern, '$1', $parsed, 1);}[/code]But somehow there are totally other values than the strings in $s_quotes, so I must be doing something wrong[/quote][tt]preg_replace [/tt]does not modify[tt] $parsed[/tt], resulting in an infinite loop. How about this?[code=php:0]<?php $str = "this is a 'string' which is made up of 'characters'"; $pattern = '[\'(.*?)\']'; preg_match_all($pattern, $str, $matches); echo '<pre>', print_r($matches, true), '</pre>';?>[/code] Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 3, 2007 Author Share Posted January 3, 2007 [quote author=effigy link=topic=119821.msg495479#msg495479 date=1167762452][quote author=Vinze link=topic=119821.msg491082#msg491082 date=1166974786]Yeah that's exactly what I did:[code=php:0]$i = 0;$pattern = '[\'(.*?)\']';while(preg_match($pattern, $parsed)){ $s_quotes[$i] = preg_replace($pattern, '$1', $parsed, 1);}[/code]But somehow there are totally other values than the strings in $s_quotes, so I must be doing something wrong[/quote][tt]preg_replace [/tt]does not modify[tt] $parsed[/tt], resulting in an infinite loop. How about this?[code=php:0]<?php $str = "this is a 'string' which is made up of 'characters'"; $pattern = '[\'(.*?)\']'; preg_match_all($pattern, $str, $matches); echo '<pre>', print_r($matches, true), '</pre>';?>[/code][/quote]Ah, sorry, I put down the code I remembered by heart as at the time I did not have it within reach. This is the full code which should not have that problem:[code=php:0]$s_pattern = '[\'(.*?)\']';$i = 0;while(preg_match($s_pattern, $parsed)){ $s_quotes[$i] = preg_replace($s_pattern, '$1', $parsed, 1); $parsed = preg_replace($s_pattern, '_|_|_|_', $parsed, 1); $i++;}[/code]But using preg_match_all () also is an option, I'll try that and you never know, it might all of a sudden work :D Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 3, 2007 Author Share Posted January 3, 2007 Unbelievable! preg_match_all() worked! Thanks a lot effigy! Quote Link to comment Share on other sites More sharing options...
effigy Posted January 3, 2007 Share Posted January 3, 2007 For the record, you do not need to use[tt] $i[/tt]: empty square brackets will result in a push to the array. Also, your code works, but not in the way you may expect. Examine this with the echo statement for debugging:[code=php:0]<?php $parsed = "'a' string with 'single' quotes"; $s_pattern = '[\'(.*?)\']'; while(preg_match($s_pattern, $parsed)){ $s_quotes[] = preg_replace($s_pattern, '$1', $parsed, 1); $parsed = preg_replace($s_pattern, '_|_|_|_', $parsed, 1); echo '<hr><pre>', print_r($s_quotes, true), $parsed, '</pre>'; }?>[/code] Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 3, 2007 Author Share Posted January 3, 2007 [quote author=effigy link=topic=119821.msg496087#msg496087 date=1167835355]For the record, you do not need to use[tt] $i[/tt]: empty square brackets will result in a push to the array. Also, your code works, but not in the way you may expect. Examine this with the echo statement for debugging:[code=php:0]<?php $parsed = "'a' string with 'single' quotes"; $s_pattern = '[\'(.*?)\']'; while(preg_match($s_pattern, $parsed)){ $s_quotes[] = preg_replace($s_pattern, '$1', $parsed, 1); $parsed = preg_replace($s_pattern, '_|_|_|_', $parsed, 1); echo '<hr><pre>', print_r($s_quotes, true), $parsed, '</pre>'; }?>[/code][/quote]I knew about the empty brackets but do not use them often as sometimes I want to do something else later on and then the array key is incremented without me wanting that.Anyway, my code did not work, preg_match_all() did and I had already tried it with "blabla' bla ' " and that worked out great too :D Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 3, 2007 Author Share Posted January 3, 2007 [quote author=effigy link=topic=119821.msg496087#msg496087 date=1167835355]For the record, you do not need to use[tt] $i[/tt]: empty square brackets will result in a push to the array. Also, your code works, but not in the way you may expect. Examine this with the echo statement for debugging:[code=php:0]<?php $parsed = "'a' string with 'single' quotes"; $s_pattern = '[\'(.*?)\']'; while(preg_match($s_pattern, $parsed)){ $s_quotes[] = preg_replace($s_pattern, '$1', $parsed, 1); $parsed = preg_replace($s_pattern, '_|_|_|_', $parsed, 1); echo '<hr><pre>', print_r($s_quotes, true), $parsed, '</pre>'; }?>[/code][/quote]Crap. I had tested it with a double-quoted string that contained a single quote, but I had to test with with [i]two[/i] quotes, and then it does not work :( Quote Link to comment Share on other sites More sharing options...
effigy Posted January 3, 2007 Share Posted January 3, 2007 I'm confused by your response. It [i]should not[/i] work with less than 2 single quotes, and it [i]should[/i] work with 2 or more single quotes. Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 4, 2007 Author Share Posted January 4, 2007 [quote author=effigy link=topic=119821.msg496275#msg496275 date=1167848768]I'm confused by your response. It [i]should not[/i] work with less than 2 single quotes, and it [i]should[/i] work with 2 or more single quotes.[/quote]When my code contains [code=php:0]echo "blabla 'single quotes' blabla ";[/code] then it won't work :( Quote Link to comment Share on other sites More sharing options...
effigy Posted January 4, 2007 Share Posted January 4, 2007 If I change [code=php:0]$parsed = "'a' string with 'single' quotes";[/code] to [code=php:0]$parsed = "blabla 'single quotes' blabla ";[/code] it works fine. If you want[tt] echo "blabla 'single quotes' blabla "; [/tt]within the string, it stills works if you escape the double quotes. Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 4, 2007 Author Share Posted January 4, 2007 [quote author=effigy link=topic=119821.msg496880#msg496880 date=1167927860]If I change [code=php:0]$parsed = "'a' string with 'single' quotes";[/code] to [code=php:0]$parsed = "blabla 'single quotes' blabla ";[/code] it works fine. If you want[tt] echo "blabla 'single quotes' blabla "; [/tt]within the string, it stills works if you escape the double quotes.[/quote]When it starts parsing the code, it first replaces all occurences of single-quoted strings with _|_|_|_ and saves the previous values in an array, then it replaces all occurences of double-quoted strings with -|-|-|- and saves the old values in an array, then it indents all the code and then puts the strings back in place. However, now I end up with [code=php:0]"blabla _|_|_|_ blabla "[/code] instead of [code=php:0]"blabla 'single quotes' blabla "[/code] Quote Link to comment Share on other sites More sharing options...
effigy Posted January 5, 2007 Share Posted January 5, 2007 Can you show some code and the expected result? I didn't know you were using another pattern for doubles. Quote Link to comment Share on other sites More sharing options...
Vinze Posted January 5, 2007 Author Share Posted January 5, 2007 [quote author=effigy link=topic=119821.msg497126#msg497126 date=1167955700]Can you show some code and the expected result? I didn't know you were using another pattern for doubles.[/quote]Good point. I now use the same pattern for single and double quotes, and now it works. However, when there is just one quote it will insert a line-break but surely I'll be able to solve that. Thanks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.