RegEx for PHP preg_replace swapping matches and matching multiple instances - php

I'm looking for a RegEx for preg_replace in PHP for the following scenario:
example string "Bjerre- Jonas, Jorgensen- Silas, Wohlert- Johan, Madsen- Bo"
desired string "Jonas Bjerre, Silas Jorgensen, Johan Wohlert, Bo Madsen"
string is a csv field and double quotes are enclosures and are part of string
any number of occurrences may exist including none - the example clearly has 4
there is a consistent - to match on separating matches to be swapped
I'm a noob at PHP and RegEx and have been playing around in the cool test arena with things like preg_replace("/^\"(?<=- )/", ""$2 $1$3"", $input_lines); with horrible results. Thanks for help!

([^," -]*)\s*-\s*([^," ]*)
Try this.See demo.
http://regex101.com/r/hI0qP0/20
$re = "/([^\", -]*)\\s*-\\s*([^,\" ]*)/m";
$str = "\"Bjerre- Jonas, Jorgensen- Silas, Wohlert- Johan, Madsen- Bo\"";
$subst = "$2 $1";
$result = preg_replace($re, $subst, $str);

Related

How to remove certain Part of JSON

Sorry for my bad English in Advance. Here is my JSON return.
https://images-na.ssl-images-amazon.com/images/M/MV5BYzc3OGZjYWQtZGFkMy00YTNlLWE5NDYtMTRkNTNjODc2MjllXkEyXkFqcGdeQXVyNjExODE1MDc#._V1_UY268_CR5,0,182,268_AL_.jpg
How can I remove the part UY268_CR5,0,182,268_AL_. Specifically that part only. And I have many of this links. Each having different strings there. For example:
https://m.media-amazon.com/images/M/MV5BYWNlMWMxOWYtZWI0Mi00ZTg0LWEwZTMtZTEzZDY0NzAxYTA4XkEyXkFqcGdeQXVyMTQxNzMzNDI#._V1_UX182_CR0,0,182,268_AL_.jpg
As shown it is different. I want to remove the part UX182_CR0,0,182,268_AL_. Each of the results I have has almost the same structure but the end part I want to remove. I am on laravel and so I am encoding my jsons result from controller. Is there anyone this can be done with php?
Update:
Here is the code I tried.
$json = json_decode($data,true);
$slice = str_replace("UY268_CR5,0,182,268_AL_","", $json);
return $slice ['poster'];
The string is removed but what about different strings with different URL's like mentioned above?
You can try with preg_replace() with the combination of lookahead and lookbehind
<?php
$re = '/(?<=_V1_)(.+?)(?=.jpg)/';
$str = 'https://m.media-amazon.com/images/M/MV5BYWNlMWMxOWYtZWI0Mi00ZTg0LWEwZTMtZTEzZDY0NzAxYTA4XkEyXkFqcGdeQXVyMTQxNzMzNDI#._V1_UX182_CR0,0,182,268_AL_.jpg';
$subst = '';
$result = preg_replace($re, $subst, $str, 1);
echo "The result of the substitution is ".$result;
?>
DEMO: https://eval.in/1044470
REFF: Regex lookahead, lookbehind and atomic groups
REGEX EXPLANATION: https://regex101.com/r/aHAw5f/1

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.

Get all alphabets in a string of words using regex (including spaces)

How would I extract all alpha characters (including space) like for example:
#john camel07 st.doe!
where I only want to get john camel stdoe.
I tried using the regex from this another SO question but it does not work.
$re = "/[^a-zA-Z ]+/";
$str = "#john camel07 st.doe!";
$subst = "";
$result = preg_replace($re, $subst, $str);
You can simply replace by empty string all non alpha and space characters.See demo.
https://www.regex101.com/r/rL8wP1/7
If your data contains unicode, this should work a bit better:
echo preg_replace("/[^[:alpha:][:space:]]/ui", '', '#john camel07 st.doe!');
Borrowed with a change from https://stackoverflow.com/a/659030/1935500

PHP Replace consecutive occurrence of characters in sentence

I want to replace all consecutive characters in each WORD if there are more than three (three being the most possible in German language, two for English so I know the output example is grammatically wrong).
Example input:
Hellooooo Louis, whaaaaaat's up pal?
Expected output:
Hellooo Louis, whaaat's up pal?
I tried to change:
preg_replace('/(\w)\1+/', '$1', $word);
to
preg_replace('/(\w)\3+/', '$1', $word);
However, it doesn't output anything.
You can use the following regex:
((\w)\2{2})\2+
See demo
Replace with $1.
IDEONE:
$re = "#((\w)\\2{2})\\2+#";
$str = "Hellooooo Louis, whaaaaaat's up pal?";
$subst = "$1";
$result = preg_replace($re, $subst, $str);
echo $result;
Output:
Hellooo Louis, whaaat's up pal?
EXPLANATION:
We capture the symbol with (\w) - it is Group 2 value. Then, we check if it is followed by the same character with \2{2} exactly 2 times, and we capture it into Group 1. Then, we match any more identical subsequent characters with the \2 backreference.
Here is a way to go:
preg_replace('/((\w)\2\2)\2+/', '$1', $word);
Also you can use \K for resetting after and replace with empty, which is a bit more efficient:
(\w)\1\1\K\1+
See regex101

preg_match parenthesized pattern

I'm trying to change a bunch of decimals in a string to two decimal points. The regex seems to match it just fine. The problem is with the replace.
This is my code:
$input_lines = "-33.873293252 151.201538015999972,-33.873175 151.201689183999946";
print preg_replace("/[0-9]+(\.[0-9][0-9]?)?/", "$0 $2", $input_lines);
Which outputs decimal that I want | truncated decimals that I don't want:
-33.87 3293252 151.20 1538015999972 ,-33.87 3175 151.20 1689183999946
So I tried changing the replacement to $0. But now the replace stopped working, and is instead giving me:
-33.873293252 151.201538015999972,-33.873175 151.201689183999946
How can I rewrite my regular expression so it gives me the desired output?
Better:
preg_replace("/(?<=\.\d\d)\d+/","",$input_lines);
Replaces all trailing decimals after the first two with nothing.
([-+]?\d+(?:\.\d{2})?)(\d*)
Try this.Replace by $1.See demo.
https://regex101.com/r/vD5iH9/46
$re = "/([-+]?\\d+(?:\\.\\d{2})?)(\\d*)/m";
$str = "-33.873293252 151.201538015999972,-33.873175 151.201689183999946";
$subst = "$1";
$result = preg_replace($re, $subst, $str);

Categories