Php's Preg_Replace Regex That Matches Multiple Lines

How to replace text over multiple lines using preg_replace

If this weren't HTML, I'd tell you to use the DOTALL modifier to change the meaning of . from 'match everything except new line' to 'match everything':

preg_replace('/(.*)<\/div>/s','abc',$body);

But this is HTML, so use an HTML parser instead.

PHP preg_replace guids over multiple lines

You can use

preg_replace_callback(
'/^(?:\s?[a-f\d]){8}\s?(?:-(?:\s?[a-f\d]){4}){4}(?:\s?[a-f\d]){8}$/mi',
function($m) {
return file_get_contents(preg_replace("~\s+~", "", $m[0]) . ".php");
},
$lines
);

See the regex demo.

The \s? inside the pattern allows matching an optional whitespace anywhere in between each char of a match. Also, with regard to the regex pattern, you need to use m flag to make ^ and $ match line boundaries (start/end of the line, not just start/end of the whole string).

You can't pass ${1} into a function within preg_replace replacement argument, you need a preg_replace_callback so that the match could be evaluated before passing it to a function.

PHP preg_replace not matching multiple lines

Use the s modifier instead of the m modifier.

The s modifier allows . to match newlines.

The m modifier makes ^ and $ match the start and end of individual lines, as opposed to the start and end of the entire string.

Side-note: The preferred syntax for the replacement is <div>$1</div>

preg_replace multiline match but preserve new lines

Ok one line using the tokenizer (Ugly thing inside):

php -r 'echo array_reduce(token_get_all(file_get_contents($argv[1])),function($c,$i){return $i[0]==321?$c.$i[1]:$c.str_repeat("\n",@count_chars($i.$i[1])[10]);});'

demo

Advantage of the tokenizer: even a string like "abc <?php echo '?>'; ?> def" is correctly parsed.

321 is the value of the constant T_INLINE_HTML (all that isn't between php tags).

10 is ASCII code for the newline character (LF). (by default, count_chars returns an associative array with the ASCII codes as keys and the number of occurrences as values).

The ugly thing is $i.$i[1] that concatenates an array with a string or a string with something not defined. @ avoids the warnings and notices. Whatever, this trick avoids a test and the number of newline characters is preserved. (see what returns token_get_all to understand the problem).


Or with DOMDocument:

php -r '$d=DOMDocument::loadHTMLFile($argv[1],8196);foreach((new DOMXPath($d))->query("//processing-instruction()")as$p)$p->parentNode->replaceChild($d->createTextNode(preg_replace("~\S+~","",$p->nodeValue)),$p);echo$d->saveHTML();'

Preg_replace with multiple lines(php)

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 $

preg_replace replace line breaks across multiple lines between two symbols

You can use

preg_replace('~(?:\G(?!\A)|^[@.])[^{]*?\K\s+~m', ' ', $text)

See the regex demo. Details:

  • (?:\G(?!\A)|^[@.]) - end of the previous successful match (\G(?!\A)) or (|) start of string (^) and then @ or .
  • [^{]*? - any zero or more (but as few as possible) chars other than {
  • \K - match reset operator that discards all text matched so far in the overall match memory buffer
  • \s+ - any one or more whitespace chars.

Note the m flag that is necessary to make ^ match start of a line, not just start of a whole string.

See the PHP demo:

$text = ".a {\r\n    // rules\r\n}\r\n\r\n.a-b,\r\n.a-b .b, .a-b.s\r\n.x .y, .x {\r\n    // rules\r\n}\r\n\r\n@a {\r\n    // rules\r\n}\r\n\r\n@k {\r\n    // rules\r\n}";
echo preg_replace('~(?:\G(?!\A)|^[@.])[^{]*?\K\s+~m', ' ', $text);

PHP Regex preg_replace multiple values between parentheses

You're going to need to go two layers, first pull everything between the [] then replace the values as needed. You can use preg_replace_callback
to accomplish this.

$string= '[mycode="gallery" type="single" id="1" data="only"]';
echo preg_replace_callback('/\[([^\]]+)\]/', function($match) {
$string = preg_replace('/\h*mycode="([^"]+)"\h*/', '$1/mycode', $match[1]);
$string = preg_replace('/\h*type="([^"]+)"\h*/', 'mycode_$1.php', $string);
$string = preg_replace('/\h*id="([^"]+)"\h*/', '?id=$1', $string);
$string = preg_replace('/\h*data="([^"]+)"\h*/', '&data=$1', $string);
return $string;
}, $string);

Your regex didn't work for a few reasons:

  1. Your strings don't end with ]
  2. Backslashes in regex escape or create meta characters, \d is a number \t is a tab.
  3. If building a URL you don't want a double quote in the returned value
  4. You also need to trim the leading and trailing whitespaces

Demo: https://3v4l.org/KDD0B



Related Topics



Leave a reply



Submit