This question already has answers here:
PHP - BBCode parser - recursive [quote] with regex and preg_replace
(2 answers)
Closed 7 years ago.
Here is my text:
$msg_text = '[quote]TEXT[/quote]';
and my preg_replace:
$msg_text = preg_replace('#\[quote\](.*?)\[\/quote\]#is', '"$1"'."\r\n", $msg_text);
And it works fine. But what when my text is looking like that:
$msg_text = '[quote]TEXT [quote]TEXT[/quote][/quote]';
?? My preg_replace doesn't work on this example. How I can replcace this text in all instances ?
Just remove the ? after .* which will remove the laziness of your pattern.
'#\[quote\](.*)\[\/quote\]#is'
What is Laziness in Regex?
Patterns like .* and .+ normally greedy, which means they will try to match as long as they can. Putting an extra ? after it we tell it to become lazy, so it will take only nearest / shortest match. So, if you remove that, it will work as it's normal way.
Note: Other use of ? is to make the previous item optional, which is not the case here, because by using * you are making that part optional already.
Learn more from here : http://www.regular-expressions.info/repeat.html
Related
This question already has answers here:
Non-greedy string regular expression matching
(2 answers)
Regex lazy quantifier behave greedy
(2 answers)
Closed 3 years ago.
I use preg_match_all to get all matches of a two-part pattern as:
/<(.*?)>[:|\s]+{(.*?)}/
In a string like:
<First>: something <second>: {Second} something <Third>: {Third}
I want to match:
<second>: {Second}
instead of:
<First>: something <second>: {Second}
Working Example
Where did I do wrong?
Use limited repeated set instead of lazy repetition inside the brackets:
<([^>]*)>[:\s]+{(.*?)}
The change is to replace <(.*?)> with <([^>]*)>. The initial version matches the first < then takes lazily any character until it finds :{Second}. If you restrict repetition, regex engine will try to start with <First>, but when it doesn't find :{...} after that, it'll try with the next <
Demo
This question already has answers here:
What does the $1$2$4 mean in this preg_replace?
(3 answers)
Closed 4 years ago.
I want to loop through an array converting specific key/value pairs that contain markup to HTML.
So an example value for $comment['comment_text'] would be:
This has *bolded* text
And should become:
This has <strong>bolded</strong> text
Here's what I've tried:
$pattern = "/\*\b.*?\b\*/i";
$newComment = preg_replace($pattern, "<strong>$&</strong>",
$comment['comment_text']);
And what I get:
This has $& text
I realize I'm mashing up Javascript with PHP, but reading about back references in PHP hasn't made things any clearer.
My strings may have multiple bolded (in markup) instances...
Any help appreciated.
UPDATE:
Apologies - I didn't realize that Stackoverflow was converting asterisks to italics. I converted the example to code.
Also, my confusion came down to the use of $0 vs. $1. Which I still don't fully understand. I thought the numbers referred to the matches in the string...so if you had 5 instances you could refer to them by $0 through $4.
If you use $0 you get:
This has <strong>*bolded*</strong> text
But if you use $1 you get the desired result.
Do this.
$pattern = "/\*\b(.*?)\b\*/";
$newComment = preg_replace($pattern, "<strong>$1</strong>", $comment['comment_text']);
Here $1 refers to the group 1 match. Here I'm supposing that you want to make text between ** bolded.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to replace text over multiple lines using preg_replace
I am trying to read some text from a file and than replacing some pattern. If I try to replace the patern from just a single string it works, but if there are multiple such strings in a file it doesnt work.
$this->session->set_flashdata('error_message', 'Naslovna vrstica je bila uspešno shranjena');
This is an example of text that I am trying to replace the replacment works ok with just this line, but not if there are other such lines in a file, which all match individualy though.
$content = file_get_contents("C:\Users\Borut\\test.txt");
$pattern="/^.*session->set_flashdata\((.*),(.*)\);$/";
$replacement="\$_SESSION[$1]=$2";
this is my code. How do you replace multiple strings as the one shown above.
The modifier you want is m. You can find all modifiers here
That said, the easiest and better regex solution would be
"/\$this->session->set_flashdata\((.*?),\s*(.*?)\);/"
Notice how there's a ? after the .* in each. This is to stop greedy matching as with yours. Also notice that the modifier isn't required either with the removal of the ^ and $
This question already has answers here:
What regex to use for this
(6 answers)
Closed 4 years ago.
I'm having troube modifying this regex. Right now it matches . or ? but I want to change it to match dot followed by a space. How do I do that?
'('/([.|?])/'
By the way, I need the grouping to stay.
What about this:
(\. |\?)
......
The easiest way would be:
'('/(\. )/'
or, if you want a space or a tab or a new-line:
'('/(\.\s)/'
Note that I only changed the part in the inner parenthesis as that part seems to be the focus of your question.
/\.\s/ should work for matching a dot followed by a space..
note: \s matches any whitespace
This question already has answers here:
My regex is matching too much. How do I make it stop? [duplicate]
(5 answers)
Closed 3 years ago.
I am quite new to the whole Regex thing and tried to do a preg_match_all in PHP which, kind of the results I wanted but the problem is it matches everything after what I actually wanted... like so:
String: This is something <code>Some code here</code> and more
Match from Regex: <code>Some code here</code> and more
Wanted match from Regex: <code>Some code here</code>
Here is my regular expression that I'm using:
/<code>(.*)<\/code>/
I think its something to do with the beginning and ending / delimiters but I'm not entirely sure.
Any help would be appreciated, thanks!
The star is greedy, meaning it will match as much as it can. Use
(.*?)
instead, making it lazy. You can also use negated character classes:
!<code>([^<]*)</code>!
EDIT: Since mvds deleted his/her answer, here's a tip: You can avoid having to escape the slash (/) if you don't use it as a delimiter, like I did above ^ (used ! )
Here's a good resource on regex:
http://www.regular-expressions.info/repeat.html
you want to make the .* be non greedy. If you put a ? after that part of the pattern it will match everything up to the next part of the regex that matches. So make the regex /<code>(.*?)<\/code>/
You need to disable greediness. Use .*? instead, I believe.
I'm not 100% sure how this is even compiling - you need to escape the second / as so:
/<code>(.*)<\/code>/
So that PHP recognises it as a character to match rather than the end of the regular expression (I think it may be compiling as a substitute regex).