glenelkins Posted May 27, 2009 Share Posted May 27, 2009 Please refer to my other post: http://www.phpfreaks.com/forums/index.php/topic,254076.0.html another quick question... now i have the content from the middle and i have it replacing with preg_replace how can i actually return everything thats between {cms params here} because i dont actually want to replace the {cms PARAMS}...{/cms} bits just whats between them Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/ Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 sorry to put a downer MrAdam but iv just modified the expression to this: $pattern = '/\{cms[^\}]*name="' . $region_id . '"[^\}]*\}([^\{]+)\{\/cms\}/'; and its matching everything to do with the {cms} tag its not matching it where the name="$region_id" so its not correct! I dont want it to pick out every tag on the page, just the one with the correclt supplied region_id Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843043 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 ? Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843049 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 getting closer! $pattern = '%{cms([^\}]*)name="' . $region_id . '"([^\}]*)}(.*){/cms}%'; Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843052 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 this is what i wanted: $pattern = '%({cms)([^\}]*)(name="' . $region_id . '")([^\}]*)(})(.*)({/cms})%'; that works splendid lol Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843054 Share on other sites More sharing options...
nrg_alpha Posted May 27, 2009 Share Posted May 27, 2009 this is what i wanted: $pattern = '%({cms)([^\}]*)(name="' . $region_id . '")([^\}]*)(})(.*)({/cms})%'; Are all those captures necessary? Note that ({cms) will be stored into $1, ([^\}]*) into $2, (name="' . $region_id . '") into $3, etc.. Seems like those captures can be simplified.. Also note that the use of .* is generally frowned upon (for speed / accuracy reasons). It is dependant on the situation of course... if there is more stuff after what the pattern matches in the string, you run into speed issues...if there is more similar stuff in the string that the pattern can match, you run into speed and accuracy issues. To have a better understanding, you can have a look at this thread (post #11 and 14). So depending on what the string looks like, it might be advisable to make .* lazy - (.*?) Also, you don't have to escape the } characters in your character class. So [^\}]* could become [^}]* Example: $region_id = 'NAME_HERE'; // I use this otherwise I have no $region_id variable to test with $replace = ' NOTHING HERE '; $str = '{cms HERE CAN HAVE ANYTHING IN ANY ORDER BUT MUST HAVE name="NAME_HERE"} ANYTHING HERE {/cms}'; $str = preg_replace('#({cms[^}]+name="' . $region_id . '"[^}]*}).+?({/cms})#', '$1'.$replace.'$2', $str); echo $str; If the ANYTHING HERE bit in the string is spread across multiple lines, simply add the s modifier after the closing delimiter (so that (.+?) can include newlines). Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843095 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 hi furthere to my earlier discussion. i have this almost working. here is my pattern: $region_id = "test_region_name"; $pattern = '%{cms[^}]*name="' . $region_id . '"[^}]*}(.*){/cms}%'; This will match a string like the following without an issue. {cms name="test_region_name" type="text"}Content Here{/cms} But when it comes to something like this: {cms name="test_region_name" type="text"}<p>Content Here</p>{/cms} It doesnt find a match (Appologies for the (.*) i have only just read your comments on that ) Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843430 Share on other sites More sharing options...
nrg_alpha Posted May 27, 2009 Share Posted May 27, 2009 I'm confused by your pattern however.. You are using a single capture on anything in between{cms.....} and {/cms} Going by your initial post, you want to replace what is in between those with something else.. how are you going to do this with the current capture setup (unless there is some miscommunication)? The way I saw it, capture anything but that section, and simply reconstruct the cms tag by inserting the first captured part, the replacement , then the second captured part. No? Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843433 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 ok the idea is we have a string something like one of these: <body> {cms name="test_name_1" type="text"}CONTENT STUFF HERE{/cms} {cms type="text" name="test_name_2" style="width: 100%;"}CONTENT STUFF HERE{/cms} </body> Now when a function is called say test() it sends over the "name" parameter: function test ( $name, $replace_content ) { } test ( "test_name_1", "REPLACE WITH THIS" ); now the pattern in this example function would be $pattern = '%{cms[^}]*name="' . $name . '"[^}]*}(.*){/cms}%'; So what its doing is looking in the html code abover for a tag that starts with {cms and within the first tag looks for the name="test_name_1" when its found that tag it will replace what is between the opening {cms name="test_name_1"} and {/cms} Following? The pattern should allow the name paremeter to fall anywhere in the opening tag so the parameters can be {cms type="text" name="name_here"}{/cms} {cms name="name_here" type="text"}{/cms} or any combination you like Now the pattern i have works fine at replacing the content bit with text, but if the content part contains HTML tags like <p>, <div> etc the pattern doesnt match so this one works fine: {cms name="test"}TEXT HERE{/cms} But this doesnt {cms name="test"}<p>TEXT HERE</p>{/cms} Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843497 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 hmm iv just changed the pattern to this: $pattern = '%{cms[^}]*name="' . $name . '"[^}]*}([^}]*){/cms}%'; And now it seems to work I thought (.*) means any character 0 or more times so why does the old one not work: $pattern = '%{cms[^}]*name="' . $name . '"[^}]*}(.*){/cms}%'; Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843509 Share on other sites More sharing options...
nrg_alpha Posted May 27, 2009 Share Posted May 27, 2009 Yes, I follow what you are saying. The dot is a wildcard so to speak that matches anything that is not a newline (\n) by default. The star is a zero or more times quantifier (but the key I was trying to explain in the link I last posted) is that this is a greedy quantifier. So by using .* instead of .*?, you run the risk of the pattern matching more than you want it to. My previous pattern seems to work fine: example: $str = <<<HTM <body> {cms name="test_name_1" type="text"}<p>CONTENT STUFF HERE</p>{/cms} {cms type="text" name="test_name_2" style="width: 100%;"}<div>CONTENT STUFF HERE</div>{/cms} </body> HTM; function replace ($name, $replace_content, $string) { $string = preg_replace('#({cms[^}]+name="' . $name . '"[^}]*}).+?({/cms})#', '$1'.$replace_content.'$2', $string); } replace('test_name_1', 'REPLACE WITH THIS', &$str); echo $str; Output: {cms name="test_name_1" type="text"}REPLACE WITH THIS{/cms} {cms type="text" name="test_name_2" style="width: 100%;"} CONTENT STUFF HERE {/cms} Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843546 Share on other sites More sharing options...
glenelkins Posted May 27, 2009 Author Share Posted May 27, 2009 ok ill get back onto it in the morning. let you know how things go Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843559 Share on other sites More sharing options...
glenelkins Posted May 28, 2009 Author Share Posted May 28, 2009 ok this is getting frustrating! The pattern matches and replaces text in this line for example: <h1>{cms type="text" name="testing1"}Testing Text Here{/cms}</h1> but it wont find a match for something like this: {cms type="text" name="testing2"} <p>Paragraph test 1</p> <p>Paragraph test 2</p> {/cms} Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843948 Share on other sites More sharing options...
glenelkins Posted May 28, 2009 Author Share Posted May 28, 2009 right now im real annoyed! I just tried it again but i put both the <p></p> areas on one line and it worked fine. Why isnt it working if the paragraph tags are on 2 lines or more? Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843950 Share on other sites More sharing options...
Daniel0 Posted May 28, 2009 Share Posted May 28, 2009 Use the multi-line modifier: #patternHere#m http://dk.php.net/manual/en/reference.pcre.pattern.modifiers.php Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843951 Share on other sites More sharing options...
glenelkins Posted May 28, 2009 Author Share Posted May 28, 2009 Daniel0 could you give me a quick example of a multi-line modifier working Clearly i should use the "m" modifier but i dont know how you use that in preg_replace or preg_match ?? Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843953 Share on other sites More sharing options...
Daniel0 Posted May 28, 2009 Share Posted May 28, 2009 preg_replace('#foo#m', 'bar', $string); ? It works like all the other modifiers and it's explained in the manual page I linked to. Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843954 Share on other sites More sharing options...
glenelkins Posted May 28, 2009 Author Share Posted May 28, 2009 well in my expression is this correct?? %({cms[^}]*name="' . $region_id . '"[^}]*}).+?m({/cms})% i have put the "m" modifier there Well that doesnt work!! I also tried this %({cms[^}]*name="' . $region_id . '"[^}]*}).+?ms({/cms})% with the "m" and "s" modifiers...still not working! Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843956 Share on other sites More sharing options...
Daniel0 Posted May 28, 2009 Share Posted May 28, 2009 You put it after the delimiter, which in this case is the percentage sign. Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843958 Share on other sites More sharing options...
glenelkins Posted May 28, 2009 Author Share Posted May 28, 2009 hmm, seems to work if i put the modifiers right at the end %({cms[^}]*name="' . $region_id . '"[^}]*}).+?({/cms})%ms Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843959 Share on other sites More sharing options...
glenelkins Posted May 28, 2009 Author Share Posted May 28, 2009 yeh thanks. all seems to work ok now...i hope Guys, thanks for your help here. I have always avoided regex but im getting the just of it now You have been a huge help Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-843960 Share on other sites More sharing options...
Adam Posted May 28, 2009 Share Posted May 28, 2009 Would save yourself a lot of time if you actually read people's responses. Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-844026 Share on other sites More sharing options...
nrg_alpha Posted May 28, 2009 Share Posted May 28, 2009 Would save yourself a lot of time if you actually read people's responses. I agree. glenelkins, I mentioned in post#5 that if the content spans across multiple lines, add the s modifier: If the ANYTHING HERE bit in the string is spread across multiple lines, simply add the s modifier after the closing delimiter (so that (.+?) can include newlines). So for example, if you had multiple lines in the text_name_1 cms; $str = <<<HTM <body> {cms name="test_name_1" type="text"} <p>CONTENT STUFF HERE</p> <p>CONTENT STUFF HERE</p> {/cms} {cms type="text" name="test_name_2" style="width: 100%;"}<div>CONTENT STUFF HERE</div>{/cms} </body> HTM; function replace ($name, $replace_content, $string) { $string = preg_replace('#({cms[^}]+name="' . $name . '"[^}]*}).+?({/cms})#s', '$1'.$replace_content.'$2', $string); } replace('test_name_1', 'REPLACE WITH THIS', &$str); echo $str; Quote Link to comment https://forums.phpfreaks.com/topic/159843-solved-continue-from-other-postpattern-match/#findComment-844116 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.