PHP preg_match (.*) not matching past line breaks [duplicate] - php

This question already has answers here:
How do I match any character across multiple lines in a regular expression?
(26 answers)
Closed 2 years ago.
I have this data in a LONGTEXT column (so the line breaks are retained):
Paragraph one
Paragraph two
Paragraph three
Paragraph four
I'm trying to match paragraph 1 through 3. I'm using this code:
preg_match('/Para(.*)three/', $row['file'], $m);
This returns nothing. If I try to work just within the first line of the paragraph, by matching:
preg_match('/Para(.*)one/', $row['file'], $m);
Then the code works and I get the proper string returned. What am I doing wrong here?

Use the s modifier.
preg_match('/Para(.*)three/s', $row['file'], $m);
Pattern Modifiers

Add the multi-line modifier.
Eg:
preg_match('/Para(.*)three/m', $row['file'], $m)

Try setting the regex to dot-all (PCRE_DOTALL), so it includes line breaks (the extra 's' parameter at the end):
preg_match('/Para(.*)three/s', $row['file'], $m);

If you don't like / at the start and and, use T-Regx
$m = Pattern::of('Para(.*)three')->match($row['file'])->first();

Related

preg_match_all not ignoring characters after pattern [duplicate]

This question already has answers here:
Regular Expression Word Boundary and Special Characters
(3 answers)
Regular expression to stop at first match
(9 answers)
Closed 2 years ago.
If my string is
<?php $str = 'hello world!'; function func_hello($str) { echo $str; }
I want to find the name of any functions in the string
I'm using the code
preg_match_all('%func_.* ?\(%', $c, $matches);
This is a basic example of what I'm doing. In the real world I'm getting results like this
func_check_error($ajax_action_check, array(
func_post('folder') == '/' || func_post(
func_check_error($fvar_ajax_action_check, array(
Whereas I want the result to be
func_check_error(
func_post(
func_check_error(
I've tried \b to set a boundary but it's not working. i.e.
preg_match_all('%\bfunc_.* ?\(\b%', $c, $matches);
The .* capture the opening parenthesis, and then the first parenthesis (after the function name) is captured, because there is the following parenthesis (the one of the array) which correspond to the \( of your pattern.
You should try a more restrictive condition on the function name, such as alphanumeric only or anything but a parenthesis, maybe replace the func_.* by func_[^(]* wich will stop at the first parenthesis match
Simple regex should work fine:
~func_.*\(~
If this is not giving the results you expect, it may be due to another issue with your code and how you're using the regex.

PHP preg_replace a pattern multiple times in the same string [duplicate]

This question already has answers here:
My regex is matching too much. How do I make it stop? [duplicate]
(5 answers)
Regular expression to stop at first match
(9 answers)
Closed 2 years ago.
I have a text string in which I'd like to replace a pattern that occurs multiple times with a tag, like this:
<?php
$str = 'A *word* is a *word*, and this is another *word*.';
preg_replace('/\*([^$]+)\*/', '<b>$1</b>', $str);
?>
However, the function is replacing the whole range from the first asterisk to the last asterisk, i.e. it doesn't separately enclose each pattern with the tag, which is what I'm trying to accomplish.
Try making the pattern lazy:
$str = 'A *word* is a *word*, and this is another *word*.';
$out = preg_replace('/\*([^$]+?)\*/', '<b>$1</b>', $str);
echo $out; // ^^ change here
This prints:
A <b>word</b> is a <b>word</b>, and this is another <b>word</b>.
For an explanation of the minor change to your regex, the updated pattern says to:
\* match *
([^$]+?) followed by any character which is NOT $, one or more times,
until reaching the
\* FIRST closing *

Regex not matching when used with PHP [duplicate]

This question already has answers here:
How do I match any character across multiple lines in a regular expression?
(26 answers)
Closed 3 years ago.
Given a fairly simple regex, I'd like to match a text between to delimiters:
___MANUAL_TICKET___
###_CLIENT_START_###
TEST
###_CLIENT_END_###
###_PROBLEM_START_###
TEST2
###_PROBLEM_END_###
###_EMAIL_START_###
xyz#test.com
###_EMAIL_END_###
To get the client I am using this regex:
###_CLIENT_START_###\s(.*?)\s###_CLIENT_END_###
which works as seen HERE.
But when I use it in my PHP Code it does not find any matches:
preg_match('####_CLIENT_START_###\s(.*?)\s###_CLIENT_END_####', $source, $matches);
(tried different regex delimiter such as / and ~, same result)
What am I doing wrong?
Note that the dot (.) by default matches any symbol but the line feed (See the documentation).
Since you have multiple line input, you need to use the PCRE_DOTALL option, which can be enabled just adding symbol s at the very end of the pattern
preg_match('####_CLIENT_START_###\s(.*?)\s###_CLIENT_END_####s', $source, $matches);
^ here

How to match only the first occurrence of String B after finding String A [duplicate]

This question already has answers here:
What is the meaning of the 'g' flag in regular expressions?
(10 answers)
Closed 3 years ago.
I have to do a mass search-and-replace with Regex on a bunch of Wordpress pages.
I have a content block where I need to replace two identical strings with different values. Therefore, I need to use Regex to find and match only the first occurrence of a string.
Everything I've done so far matches both occurrences. Here's what I have... trying to only match the first occurrence of a string after a certain string. However, the following regex matches both occurrences.
(item="Finish")*(8678)
I would like to see only the first occurrence of that string be matched.
https://regexr.com/4di9c
Here's the source string:
[vc_row class="options-tabs-section"][vc_column][vc_tta_tabs active_section="1"][vc_tta_section title="Finish" tab_id="finisha2ec-a4f1"][vc_media_grid element_width="3" item="8678" grid_id="vc_gid:1557243701236-783a77b3-2fb2-8" include="717,716,715,714,713,712,711,709,708,707"][/vc_tta_section][vc_tta_section title="Glass" tab_id="glassa2ec-a4f1"][vc_media_grid element_width="3" item="8656" grid_id="vc_gid:1557243701239-312d0b1e-25cd-9" include="964,972,724,971,969,968,967,966,965"][/vc_tta_section][vc_tta_section title="Handles" tab_id="handlesa2ec-a4f1"][vc_media_grid element_width="3" item="8678" grid_id="vc_gid:1557243701240-a408e67a-7aab-7" include="8661,8667,8660,8664,8665,8663,8662,8668,8666,8669"][/vc_tta_section][/vc_tta_tabs][/vc_column][/vc_row]
EDIT: I realize I'm probably thinking too hard here. Here's what I did that got me the answer I needed... Probably didn't need to do regex. I simply removed the global flag and went step-by-step:
<?php
$input='[vc_row class="options-tabs-section"][vc_column][vc_tta_tabs active_section="1"][vc_tta_section title="Finish" tab_id="finish84e3-bb24"][vc_media_grid element_width="3" item="4566" grid_id="vc_gid:1551131488971-e1d811df-ddaf-8" include="717,716,715,714,713,712,711,709,708,707"][/vc_tta_section][vc_tta_section title="Glass" tab_id="glass84e3-bb24"][vc_media_grid element_width="3" item="174" grid_id="vc_gid:1551131488974-85d653d4-4558-1" include="964,972,724,971,969,968,967,966,965"][/vc_tta_section][vc_tta_section title="Handles" tab_id="handles84e3-bb24"][vc_media_grid element_width="3" item="174" grid_id="vc_gid:1551131488975-8b255d93-ab50-6" include="961,960,959,913,912,911,910,909,908,907"][/vc_tta_section][/vc_tta_tabs][/vc_column][/vc_row]';
$output=preg_replace('/961,960,959,913,912,911,910,909,908,907/', '8661,8667,8660,8664,8665,8663,8662,8668,8666,8669', $input );
$output=preg_replace('/4566/', '8678', $output);
$output=preg_replace('/174/', '8656', $output);
$output=preg_replace('/174/', '8678', $output);
echo $output;
echo "\n";
There needs to be more information to properly answer your question, but if you are looking to match the first occurance and were to use the preg_match() PHP function, you could do it like so:
preg_match('/(item="Finish")*(8678)/', $yourString, $matches);
var_dump($matches[0]);
PHPFiddle
Depending on what you are doing, this may not solve it, but most of the PRCE/Regular Expression Functions in PHP will use similar parameters and function in a similar way.

php preg_replace returns unknown modifier '+'? [duplicate]

This question already has answers here:
Warning: preg_replace(): Unknown modifier
(3 answers)
Closed 3 years ago.
trying to fix this regex. Its supposed to find any hyperlinks in a string and put anchor tags around them. Keeps coming back, unkown identifier '+'. I thought the plus sing was part of regex?
<?php
//replace links with clickable links
// match protocol://address/path/
$comments = preg_replace("[a-zA-Z]+://([.]?[a-zA-Z0-9_/-])*", "\\0", $comments);
// match www.something
$comments = preg_replace("(^| )(www([.]?[a-zA-Z0-9_/-])*)", "\\1\\2", $comments);
?>
any help appreciated.
A PCRE patterns (that's what you give to preg_replace) needs to be enclosed by delimiters:
~[a-zA-Z]+://([.]?[a-zA-Z0-9_/-])*~
Here the ~ are the delimiters. I used this char because it doesn't occur in the rest of the regex.
To explain the error: PCRE thinks that [ is the delimiter (as the first char always is the delimiter). So when it find the corresponding closing delimiter ] is considers everything after it a modifier. And as there is no + modifier you get an error ;)
try replacing
"[a-zA-Z]+://([.]?[a-zA-Z0-9_/-])*", "\\0"
with
r'[a-zA-Z]+://([.]?[a-zA-Z0-9_/-])*', '\\0'

Categories