steamngn
asked on
PHP regex expression to capture and replace part of string
Say I have a string and within that string are multiple occurrences of a string similar to "@41|8:00|10/01/2015@".
What I need to do is find each of these strings and remove everything between the two "|" so "@41|8:00|10/01/2015@" needs to become "@41|10/01/2015@".
I can find and replace the entire string with
I just cannot get my head around the expression...
Andy
What I need to do is find each of these strings and remove everything between the two "|" so "@41|8:00|10/01/2015@" needs to become "@41|10/01/2015@".
I can find and replace the entire string with
preg_replace('/@[^>]*@/', 'replaced', $teststr);
but how do I find a replace only that center portion?I just cannot get my head around the expression...
Andy
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
excellent!
Expression Explained
/(@\d+)\|.*?\|(.*?@)/
(@\d+) - match anything that starts with a '@' followed by one or more digits (\d). The ( ) around the expression means we want to save it as a parameter so that we can use it in the replace
\| - | is a special char in regex (means or) - so we have to escape it with a '\' - we don't need it because we will recreate it in the replace.
.*? - no ( ) because we are not interested in this bit. the .* says match anything the ? says don't be greedy.
.* will match anything which would include the next \| - however we want it to stop matching when it hits the \| so we put a ? after the .* to say don't be greedy take only what you can up until the next thing we are looking for - in this case the \|
\| - the next | delimiter
(.*?@) - the ( ) says keep this for use in the replace (this will be parameter #2) - says match anything but don't be greedy (?) until you hit a @ - include that in the match and then stop.
Why do we not put a ? (don't be greedy) after the \d+ in the first match?
Answer: we could but it is not necessary. The \d specifier only matches 0-9 - so as soon as it hits a non digit it stops anyway.
What do the opening and closing '/' mean
Answer: they are just regular expression delimiters saying where it starts and where stops.
Now for the replace - easy
\1|\2
\1 means the first saved match - (@\d+)
| - insert a | - we don't need to escape it because in the replace string the | character is just a |
\2 - the second matched parameter (.*?@)
/(@\d+)\|.*?\|(.*?@)/
(@\d+) - match anything that starts with a '@' followed by one or more digits (\d). The ( ) around the expression means we want to save it as a parameter so that we can use it in the replace
\| - | is a special char in regex (means or) - so we have to escape it with a '\' - we don't need it because we will recreate it in the replace.
.*? - no ( ) because we are not interested in this bit. the .* says match anything the ? says don't be greedy.
.* will match anything which would include the next \| - however we want it to stop matching when it hits the \| so we put a ? after the .* to say don't be greedy take only what you can up until the next thing we are looking for - in this case the \|
\| - the next | delimiter
(.*?@) - the ( ) says keep this for use in the replace (this will be parameter #2) - says match anything but don't be greedy (?) until you hit a @ - include that in the match and then stop.
Why do we not put a ? (don't be greedy) after the \d+ in the first match?
Answer: we could but it is not necessary. The \d specifier only matches 0-9 - so as soon as it hits a non digit it stops anyway.
What do the opening and closing '/' mean
Answer: they are just regular expression delimiters saying where it starts and where stops.
Now for the replace - easy
\1|\2
\1 means the first saved match - (@\d+)
| - insert a | - we don't need to escape it because in the replace string the | character is just a |
\2 - the second matched parameter (.*?@)
You are welcome.
ASKER
Julian,
I went round and round ALL DAY on this.... and now with your insight I see where I was going wrong!
Excellent help, Thank you
Andy
I went round and round ALL DAY on this.... and now with your insight I see where I was going wrong!
Excellent help, Thank you
Andy
Again you are welcome Andy - glad I could be of assistence.
ASKER
Right on the money! Ok, without taking up your entire day can you break this out a bit and explain it to me? I fought with this all day and you hit it out of the park first pitch<insanely jealous></insanely jealous>
Andy