pr0no Posted February 10, 2012 Share Posted February 10, 2012 Consider the following string $text = "Dat foo 13.45 and $600 bar {baz:70} and {8}"; I need to label all numbers in $text, except for when they are between curly braces. I now have this: preg_replace("/(?<!{)([0-9]+(?:\.[0-9]+)?)(?!})/","{NUMBER:$0}",$text); which outputs: Dat foo {NUMBER:13.45} and $ {NUMBER:600} bar {baz: {NUMBER:7} 0} and {8} However, the desired output is: Dat foo {NUMBER:13.45} and ${NUMBER:600} bar {baz:70} and {8} where numbers between { and } are ignored, even if they are surrounded by alfanumerical (or other) characters. In other words - how do I need to adjust the regex to completely ignore whatever there is between curly braces? Your help would be greatly appreciated! Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/ Share on other sites More sharing options...
AyKay47 Posted February 11, 2012 Share Posted February 11, 2012 okay I have cooked something up for you: echo preg_replace("~(?<![a-z{:])([0-9.]++)(?![a-z}])~i","{NUMBER: $1}","Dat foo 13.45 and $600 bar {baz:70} and {8}"); output: Dat foo {NUMBER: 13.45} and ${NUMBER: 600} bar {baz:70} and {8} I optimized your code a little and tweaked it a bit based on the specifications in your post. I believe the main issue with your pattern is that the negative lookbehind would allow any other character other than an opening curly brace "{" to preced it. so things like {teststring90test} would pass. Since you had the negative lookahead disallowing the number to be follwed by a closing curly brace, the regex had no choice but to only match the 7 in {baz:70} since it could not match the 70 which it wanted to. Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1316909 Share on other sites More sharing options...
salathe Posted February 11, 2012 Share Posted February 11, 2012 AyKay47, your solution is not "based on the specifications in your post". Give it a go with {:70:} The OP said "numbers between { and } are ignored, even if they are surrounded by alfanumerical (or other) characters." Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1316982 Share on other sites More sharing options...
AyKay47 Posted February 11, 2012 Share Posted February 11, 2012 AyKay47, your solution is not "based on the specifications in your post". Give it a go with [samp]{:70:}[/samp] The OP said "numbers between { and } are ignored, even if they are surrounded by alfanumerical (or other) characters." thanks salathe, I was in a hurry to get out the door before I put this together so I did not have time to thoroughly test it, I appreciate you pointing out the hole in the pattern. I have revised the pattern and also made it a bit simpler, but more powerful. $pattern = "~([\d.]+)(?![^{]*})~"; this will match any digit along with a decimal as long as it finds an opening bracket before it finds a closing bracket. Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317013 Share on other sites More sharing options...
salathe Posted February 11, 2012 Share Posted February 11, 2012 That still doesn't do what the OP asked for. Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317032 Share on other sites More sharing options...
AyKay47 Posted February 11, 2012 Share Posted February 11, 2012 That still doesn't do what the OP asked for. I disagree Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317039 Share on other sites More sharing options...
salathe Posted February 11, 2012 Share Posted February 11, 2012 I disagree {:70{}} Repeating the OP for clarity: "I need to adjust the regex to completely ignore whatever there is between curly braces". Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317041 Share on other sites More sharing options...
AyKay47 Posted February 11, 2012 Share Posted February 11, 2012 I disagree {:70{}} Repeating the OP for clarity: "I need to adjust the regex to completely ignore whatever there is between curly braces". i had thought of that, but im not going to assume that there can be nested curly braces, since I am assuming that this is a pre-formatted string. That is what he is getting until I am notified otherwise by the OP... Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317046 Share on other sites More sharing options...
ragax Posted February 13, 2012 Share Posted February 13, 2012 Wow, a fun little regex puzzle. I do see both of you guys' points. From an overall "web forum contribution ethos" standpoint, I confess that I'd approach the question like Aykay... Trying to keep it simple first before pulling out the big guns... But everyone is different, as can be seen by the difference in style and depth of responses on this very forum. For my own taste in regex, I found Aykay's solution elegant and relatively lightweight. (But taste is a personal matter.) If you wanted to kick yourself in the shins and go "all the way" just for the hell of it, that would be a bit of a mission, wouldn't it? Without fully exploring the question, I imagine that I'd have to cut the string into chunks, using a recursive pattern to identify (and leave out) the bits with curly braces. Thanks for the chance to rave about the choices we make when we answer questions. When the OP disappears, as often happens, it can feel like speaking in the dark... Unless someone else from the forum chimes in. Which happens all the time, and I appreciate that. (Thanks guys.) Wishing you all a fun day Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317862 Share on other sites More sharing options...
ragax Posted February 13, 2012 Share Posted February 13, 2012 Hi AyKay, hi Salathe, Just because I have nothing better to do before breakfast this morning and I love regex puzzles, here is an answer that addresses nesting. Input: Replace 37.2 or $10 not {5} nor {a 6} nor {{7}} nor {an {8} or {{9}}!} but {unbalanced 10 Code: <?php $string='Replace 37.2 or $10 not {5} nor {a 6} nor {{7}} nor {an {8} or {{9}}!} but {unbalanced 10'; $regex=',([^{]++)({(?[^{}]*+)(??-2)(?-1))*)})?,'; echo preg_replace_callback($regex,'call_me',$string); function call_me ($m) { $cleaned=preg_replace(',\d+(?:\.\d+)?,','{NUMBER:\0}',$m[1]); $donttouch=isset($m[2])?$m[2]:''; return $cleaned.$donttouch; } ?> Output: Replace {NUMBER:37.2} or ${NUMBER:10} not {5} nor {a 6} nor {{7}} nor {an {8} or {{9}}!} but {unbalanced {NUMBER:10} A note for regex lovers: the recursive part of the expression is home-made, rather than the one everyone copies from Jeffrey's book. In my benchmarks, it matches about 20 percent faster, but fails about twenty percent slower. For my taste Aykay's solution is still a perfect answer until the OP gives signs of life. An expression like the one in this post is a mixed blessing: it works, but it's hard to explain, and even harder to maintain if the person who receives it doesn't fully understand it. Wishing you all a beautiful day! Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1317886 Share on other sites More sharing options...
ragax Posted February 19, 2012 Share Posted February 19, 2012 When the OP disappears, as often happens, it can feel like speaking in the dark... Unless someone else from the forum chimes in. Which happens all the time, and I appreciate that. On the other hand, sometimes the silence can be quite deep. Quote Link to comment https://forums.phpfreaks.com/topic/256852-filter-number-from-string-except-when-between-curly-braces/#findComment-1318997 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.