Nyla Posted January 4, 2015 Share Posted January 4, 2015 How come preg_replace won't traverse multiple lines? <?php $str = ' one two three four '; echo preg_replace("/two.*three/",'xxx',$str); ?> The result should be: one xxx four ...but it looks like preg_replace doesn't go from one line to the next? Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted January 4, 2015 Share Posted January 4, 2015 Read the manual, especially the part about the “s” modifier. Quote Link to comment Share on other sites More sharing options...
Nyla Posted January 4, 2015 Author Share Posted January 4, 2015 Well Mister Mister, since I don't like being bossed around, I'm going to read, learn, and MEMORIZE the entire PHP manual cover-to-cover, EXCEPT the part about the "s modifier." So there...I'll teach YOU a lesson! LOL THANK YOU!!! Quote Link to comment Share on other sites More sharing options...
hansford Posted January 4, 2015 Share Posted January 4, 2015 echo preg_replace('/two.*three/s','xxx',$str); But I "believe" this is more efficient. echo preg_replace('/two\s+three/','xxx',$str); 1 Quote Link to comment Share on other sites More sharing options...
Nyla Posted January 4, 2015 Author Share Posted January 4, 2015 Hansford, that's cool! But how come your method works? I believe " \s " means space, right? Well does preg_replace treat "new lines" (e.g. "traversing lines" as I referred to?) as spaces? If so, why doesn't .* or .*? work? Doesn't that mean "everything up to" ??? I'm so dumb. I'll learn fast, though, whatever you tell me. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted January 4, 2015 Share Posted January 4, 2015 (edited) I believe " \s " means space, right? Well does preg_replace treat "new lines" (e.g. "traversing lines" as I referred to?) as spaces? The \s pattern matches a single whitespace character. This includes the space character, the tabular and the various newline characters. If so, why doesn't .* or .*? work? Doesn't that mean "everything up to" ??? No. As I already said, the meaning of the “.” pattern depends on the regex modifiers. By default, “.” matches any character except a newline. If you want it to match a newline as well, you need the “s” modifier. The “*” is a greedy quantifier: It consumes as many repetitions as possible. On the other hand, “*?” is a non-greedy quantifier, which means it consumes as few repetitions as possible. Using “.” is generally poor practice, especially when combined with a greedy quantifier. What happens is this: The pattern first consumes the entire line or even the entire remaining input (depending on the modifiers). Since there's no input left, the regex parser can't find a match for the next patterns. So it goes one step back and tries again (this is called backtracking). If it still can't find a match, it again goes one step back and tries again. And so on. This trial-and-error procedure is obviously extremely inefficient. In the worst case, the parser has to go all the way back to where it started and then starts over. Not good. When you write regexes, be specific. Tell the parser exactly what you want. If you use vague patterns, then the parser has to guess what you want and will take much longer. I also recommend that you read up the basics of regular expressions. There are tons of online resources and books. Just google for it. Edited January 4, 2015 by Jacques1 Quote Link to comment Share on other sites More sharing options...
Nyla Posted January 4, 2015 Author Share Posted January 4, 2015 Thank you Jacques, I'm like a "trial-and-error" parser hahaha -- I try and try and try. But your post is very clear and articulate, and I probably won't have to bother you again for a long time. I appreciate your help, and appreciate you helping me solve the problem at hand. Thank you again, and happy new year! 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.