preg_replace issue. Character class inside other character class - php

I have a fragment in text like
;flat
CID_999999 = 99999999
CID_999999 = 99999999
CID_999999 = 99999999
CID_999999 = 99999999
where 999999 are some numbers. I want to find this fragment by regexp.
When I use this regex:
preg_replace('/;flat[\s\r\n]+[CID_0-9]+\s=\s[0-9]+\n/','REPLACEMENT',$content);
it replaces ;flat and first CID string.
So, I suppose that if I put [CID_0-9]+\s=\s[0-9]+\n part in character class []+it will remove all CID strings. But if I do it it doesn't replace anything. So I don't understand something in regex. What am I doing wrong?
I thought that expected output is clear, but ok. I should replace all fragment by REPLACEMENT.

Use lookbehind if you are trying to match just the digits after the = and before the newline
For more accurate matching use CID[0-9]+ rather than [CID0-9]+
preg_replace('/(?<;flat[\s\r\n]+CID_[0-9]+\s=\s)[0-9]+(?=\n)/','REPLACEMENT',$content);

You don't need a character class ([...]); you need a group ((...)). Your code should look like this:
preg_replace('/;flat[\s\r\n]+([CID_0-9]+\s=\s[0-9]+\n?)+/', 'REPLACEMENT', $content);
Note the ? at the end, just in case your last line isn't terminated with a new line (\n) character.
Demo

;flat\s*|(?!^)\G(CID_\d+\s*=\s*\d+\s*)
Try this.Replace by $1.See demo.
https://regex101.com/r/gQ3kS4/7
$re = "/;flat\\s*|(?!^)\\G(CID_\\d+\\s*=\\s*\\d+\\s*)/";
$str = ";flat\nCID_999999 = 99999999\nCID_999999 = 99999999\nCID_999999 = 99999999\nCID_999999 = 99999999\n;";
$subst = "$1";
$result = preg_replace($re, $subst, $str);

Related

PHP: replace text in the last brackets in string

i thinking how can I replacing last item of form names like this:
content[1]
content[1][officeImage]
content[2][officeImage]
content[3][something][officeImage]
...
Depth of "array" can be infinity and I need replace last of him like this:
content[replaced]
content[1][replaced]
content[2][replaced]
content[3][something][replaced]
...
Is here someone who can write preg_replace() or etc?
Thanks
Edit:
I have this:
preg_replace('~\[.*!?\]~', '[replaced]', $parent);
But it return from "content[1][officeImage]" this "content[replaced]" :[
Try this:
preg_replace('~^.*\[\K[^]]+~m', 'replaced', $parent);
The m (multi-line) modifier is only necessary if $parent contains multiple lines needing to be replaced at once.
The big trick here is starting with ^.*\[\K. This says match everything starting with the beginning of the line up to a \[. Since this is a "greedy" repetition it will keep going until the last instance (. doesn't match newlines without the s modifier). The \K throws away everything matched so we only are replacing what's inside the brackets.
You can use this code:
$re = "/\\[([^]]*)\\][^]]*$/m";
$str = "content[1]\ncontent[1][officeImage]\ncontent[2][officeImage]\ncontent[3][something][officeImage]";
$subst = "[replacement]";
$result = preg_replace($re, $subst, $str);
See it live PHP or live Regex
Try this:
$string = 'content[3][something][officeImage]';
$replaced = 'somestring';
$result = preg_replace('/(.*\[)(.*?)]$/m','$1'.$replaced.']',$string);

Encode equal sign in query string with regex

I have a query string that may look like one of the following:
?key=aa=bb
?key=aa=bb=cc
?key=aa=bb&key2=cc
etc.
What I want to do is replace the equal sign in the value part only. So it should result in this:
?key=aa%3dbb
?key=aa%3dbb%3dcc
?key=aa%3dbb&key2=cc
I'm trying to do that with the following regex by using a look ahead. But it's not doing anything.
echo preg_replace("/=(?=[^&])=/", "%3d", 'http://www.example.com?key=aaa=bbb=ccc&key3=dddd');
Example code here
How can I make this work?
(\bkey\d*)=(*SKIP)(*F)|=
Try this.See demo.
https://regex101.com/r/hR7tH4/13
$re = "/(\\bkey\\d*)=(*SKIP)(*F)|=/m";
$str = "\n ?key=aa=bb\n ?key=aa=bb=cc\n ?key=aa=bb&key2=cc\n";
$subst = "%3d";
$result = preg_replace($re, $subst, $str);
You don't need regex, use the proper tools. parse_url() to get the query string (and whatever else you want), then parse_str() to get an array of the var/vals. Then http_build_query() will encode for you:
$query = parse_url('http://www.example.com?key=aaa=bbb=ccc&key3=dddd', PHP_URL_QUERY);
parse_str($query, $array);
$result = http_build_query($array);
Here is another version of a regex based on the same approach as vks':
[&?][^&=]+=(*SKIP)(*FAIL)|=
Regex explanation:
[&?] - Match & or ? literally
[^&=]+ - Match characters other than & and =
= - Match = (so, we matched a key)
(*SKIP)(*FAIL) - Verbs that fail the match at this point (we do not replace this = we found after key)
= - We match any other = and we'll remove it.
Here is IDEONE demo:
$re = "/[&?][^&=]+=(*SKIP)(*FAIL)|=/";
$str = "http://google.com?key=aa=bb\nhttp://google.com?key=aa=bb=cc\nhttp://google.com?key=aa=bb&key2=cc";
$result = preg_replace($re, "%3d", $str);
echo $result;
What about this?
preg_replace_callback("/=([^&$]+)/", "myReplace", "http://www.example.com?key=aaa=bbb=ccc&key3=dddd");
function myReplace($matches) {
return "=" . urlencode($matches[1]);
}
Just gonna add an addendum, explaining your specific attempt:
preg_replace("/=(?=[^&])=/",
↑ ↑
While the lookahead was a nice idea, it really just would match a single character. And in this case just would have asserted the very next character not to be &.
You could refashion it into:
preg_replace("/=([^&=]+)\K=/",
↑
Which I guess is what you tried. Note that this merely ignores every second =………= equal sign. So would only suit your simple example query strings, not more plentiful unescaped characters within.

How to replace a particular text between 2 characters in a string

I have a doubt in regular expression. I want to replace a particular text which is present in 2 characters in a string.
Example:
$my_string = "newtext!234##random_text##weludud";
$new_text = 'replaced_text";
In myabove string I want to replace the text between my characters ##. So in the above string I want to replace random_text with replaced_text.
So my output will be newtext!234##replaced_text##weludud
If ## text ## appears only once in the string, you can use explode.
$my_string = "newtext!234##random_text##weludud";
$new_text = 'replaced_text';
$var = explode('##',$my_string); //create an array with 3 parts, the middle one being the text to be replaced
$var[1]=$new_text;
$my_string=implode('##',$var);
(?<=##)(?:(?!##).)*(?=##)
Try this.Replace by replace_text.See demo.
http://regex101.com/r/sU3fA2/40
$my_string = "newtext!234##random_text##weludud";
$replace = 'replaced_text';
$replaced_text = preg_replace('#(#)(.*)(#)#si', "$1$replace$3", $my_string);
echo $replaced_text;
Working demo

How to extract a collection of numbers from a string?

I need to extract a project number out of a string. If the project number was fixed it would have been easy, however it can be either P.XXXXX, P XXXXX or PXXXXX.
Is there a simple function like preg_match that I could use? If so, what would my regular expression be?
There is indeed - if this is part of a larger string e.g. "The project (P.12345) is nearly done", you can use:
preg_match('/P[. ]?(\d{5})/',$str,$match);
$pnumber = $match[1];
Otherwise, if the string will always just be the P.12345 string, you can use:
preg_match('/\d{5}$/',$str,$match);
$pnumber = $match[0];
Though you may prefer the more explicit match of the top example.
Try this:
if (preg_match('#P[. ]?(\d{5})#', $project_number, $matches) {
$project_version = $matches[1];
}
Debuggex Demo
You said that project number is 4 of 5 digit length, so:
preg_match('/P[. ]?(\d{4,5})/', $tring, $m);
$project_number = $m[1];
Assuming you want to extract the XXXXX from the string and XXXXX are all integers, you can use the following.
preg_replace("/[^0-9]/", "", $string);
You can use the ^ or caret character inside square brackets to negate the expression. So in this instance it will replace anything that isn't a number with nothing.
I would use this kind of regex : /.*P[ .]?(\d+).*/
Here is a few test lines :
$string = 'This is the P123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
$string = 'This is the P.123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
$string = 'This is the P 123 project, with another useless number 456.';
$project = preg_replace('/.*P[ .]?(\d+).*/', '$1', $string);
var_dump($project);
use explode() function to split those

Regex replacement with multiple occurances and different values within a string in PHP

I have this code:
<object height="510" width="650">height="510"width="650">
or this code:
<objectheight="345"width="123'> height='456'width=789>
The quotes around the values could be double, single or none. And the words could be put together or there could be one or more whitespaces. And what is important the digits as a value could be anything
So, I need to replace the integervalue in height="510" (or height='123' or height=456) with my own variable $height_val.
My code so far:
$height_val = "640";
$pattern = ??? // this regex I need to find out
$replacement = $height_val;
$string = '<objectheight="345"width="123\'> height=\'456\'width=789>'
$result = preg_replace($pattern, $replacement, $string);
And the final result should be <objectheight="640"width="123\'> height=\'640\'width=789>
The reg-ex I'd use is: height=(["']*)[0-9]*(["']*). This ensures you only get the height value with any non-alpha digit after the equals followed by an any length number.
$height_val = "640";
//$pattern = '/height=\D[0-9]*\D/' // pre comments regex
$pattern = height='/(["']*)[0-9]*(["']*)/'; //new regex
$replacement = $height_val;
$string = '<objectheight="345"width="123\'> height=\'456\'width=789>'
$result = preg_replace($pattern, $replacement, $string);
I've tested it on the following variables:
<object height="510" width="650">height="510"width="650">
<objectheight="510" width="650">height="510"width="650">
<object height='510' width="650">height="510"width="650">
<objectheight='510'width="650">height="510"width="650">
value="width=650&height=515&plugins=http://
Going forward I would recommend you try using a RegEx tester to try your own combinations. You can also use this regex reference to give you help with character classes.
Updated:
If you wish to allow for no quotation marks too use the following:

Categories