Replace in a string a series of numbers (id card) PHP - php

I would like to replace the first 5 digits or the last 4 of the id card, it always comes before a "-" and a space
String:
$string1 = "** GALLARDO SERGIO - 74276932M";
$string2 = "** MONTOLIA ANTONIO - 74736619E";
I have two options to show the result, the first 5 numbers of the id card or the last 4
$result1= "** GALLARDO SERGIO - *****932M";
$result2= "** MONTOLIA ANTONIO - 74736****";
for the second option I have used a substr () but it does not work if a string comes with another type of text
$result= substr($string1, 0, -4) . "****";
thanks

You can leverage
preg_replace('~^(.*-\h+)\d{5}~', '$1*****', $text);
The regex matches
^ - start of string
(.*-\h+) - Capturing group 1: any zero or more chars as many as possible, up to the rightmost - and one or more horizontal whitespaces
\d{5} - five digits.
In the replacement pattern, $1 refers to the value of Group 1.
See the regex demo.

Related

Regex match specific string without other string

So I've made this regex:
/(?!for )€([0-9]{0,2}(,)?([0-9]{0,2})?)/
to match only the first of the following two sentences:
discount of €50,20 on these items
This item on sale now for €30,20
As you might've noticed already, I'd like the amount in the 2nd sentence not to be matched because it's not the discount amount. But I'm quite unsure how to find this in regex because of all I could find offer options like:
(?!foo|bar)
This option, as can be seen in my example, does not seem to be the solution to my issue.
Example:
https://www.phpliveregex.com/p/y2D
Suggestions?
You can use
(?<!\bfor\s)€(\d+(?:,\d+)?)
See the regex demo.
Details
(?<!\bfor\s) - a negative lookbehind that fails the match if there is a whole word for and a whitespace immediately before the current position
€ - a euro sign
(\d+(?:,\d+)?) - Group 1: one or more digits followed with an optional sequence of a comma and one or more digits
See the PHP demo:
$strs= ["discount of €50,20 on these items","This item on sale now for €30,20"];
foreach ($strs as $s){
if (preg_match('~(?<!\bfor\s)€(\d+(?:,\d+)?)~', $s, $m)) {
echo $m[1].PHP_EOL;
} else {
echo "No match!";
}
}
Output:
50,20
No match!
You could make sure to match the discount first in the line:
\bdiscount\h[^\r\n€]*\K€\d{1,2}(?:,\d{1,2})?\b
Explanation
\bdiscount\h A word boundary, match discount and at least a single space
[^\r\n€]\K Match 0+ times any char except € or a newline, then reset the match buffer
€\d{1,2}(?:,\d{1,2})? Match €, 1-2 digits with an optional part matching , and 1-2 digits
\b A word boundary
Regex demo | Php demo
$re = '/\bdiscount\h[^\r\n€]*\K€\d{1,2}(?:,\d{1,2})?\b/';
$str = 'discount of €50,20 on these items €
This item on sale now for €30,20';
if (preg_match($re, $str, $matches)) {
echo($matches[0]);
}
Output
€50,20

Extract last 2 snippets from string (PHP)

In my code I call the following up
{$item.articlename}
this one has the content:
"Red Blue Green Yellow Black"
I just want to have the last two words in the string.
"Yellow Black"
I tried to delete the first words with regex_replace,
{$item.articlename|regex_replace:"/^(\w+\s)/":" "}
but the number of words at the beginning varies, so I always want to have the last two words.
I would appreciate any hint.
You could match the last 2 words using \w+ to match 1+ word characters and \h+ to match 1+ horizontal whitespace characters. Use an anchor $ to assert the end of the string.
Note that \s also matches a newline.
\w+\h+\w+$
Regex demo
If you want to use a replacement, you could replace using the first capturing group and use a word boundary \b before the first \w+
^.*(\b\w+\h+\w+)$
^ Start of stirng
.* Match any char except a newline 0+ times
( Capture group 1
\b\w+\h+\w+ Wordboundary, 1+ word chars, 1+ horizontal whitespace chars, 1+ word chars
) Close group 1
$ End of string
Regex demo
In the replacement use group 1 $1
How about this:
$string = "Red Blue Green Yellow Black";
$arr = explode(" ", $string);
$arr = array_slice($arr, -2, 2, true);
$result = implode(" ", $arr);
Assuming last 2 words would always exist, you can use simple explode() and array_slice() with a negative offset to get them. Later, you can glue them using join.
<?php
$str = "Red Blue Green Yellow Black";
echo join(" ",array_slice(explode(" ",trim($str)),-2));
Demo: https://3v4l.org/7FJ9n
In your code, it would look like
{{ join(" ",array_slice(explode(" ",trim($item.articlename)),-2)) }}

PHP regex replace 'minus'

I am trying to remove the 'minus' from a string, but if there are three in sequence I want to keep one.
For example:
today-is---sunny--but-yesterday---it-wasnt
Become:
today is - sunny but yesterday - it wasnt
I was trying to str_replace the - but obviously is removin all of them.
Basicaly I want to remove maximum 2 in sequence.. If there's more keep it.
Not smart enough to make it into one regex so here's 2:
$string = "today-is---sunny--but-yesterday---it-wasnt";
$string = preg_replace("/\b-{1,2}\b/", " ", $string);
$string = preg_replace("/\b-{3,}\b/", " - ", $string);
Seems to work
I would do this in 2 steps using regex.
First, replace the minus symbol with a space if there is 1 or 2 surrounded by word boundries.
preg_replace("/(\b(-){1,2}\b)/", " ", $string);
Pattern (regex101):
word boundry | minus sign (1 or 2) | word boundry
Then, replace all instances of 3 or more minus signs with a minus sign surrounded by spaces.
preg_replace("/(\b(-){3,}\b)/", " - ", $string);
Pattern (regex101):
word boundry | minus sign (3 or more) | word boundry
Note: None of the parenthesis in my example code patterns are required, buet I believe they help readability.
I personally love the way regex101 lays out exactly what is happening in the top right corner of the website with a given pattern, so if you'd like to learn more about how this (or other regex patterns) work, then regex101 is a wonderful resource.
Solution with a callback:
$new = preg_replace_callback(
'/[-]+/',
function ($m) {
return 2 < strlen($m[0])? ' - ' : ' ';
},
'today-is---sunny--but-yesterday---it-wasnt'
);
// today is - sunny but yesterday - it wasnt
Okay, I think this handles the cases mentioned by your updates
$string = "today-is---sunny--but-yesterday---it-wasnt----nothing-----five";
$newstring = preg_replace("/(\-{1,2})(?!\-)/", " ", $string);
$newstring = preg_replace("/(\-+)/", " $1", $newstring);
echo $newstring;
Output is:
today is - sunny but yesterday - it wasnt -- nothing --- five
DEMO
So it matches 1 or 2 dashes that are not followed by a dash and replaces with a space. In the case of more than 2 consecutive dashes, this means it matches only the last 2 in the consecutive string. Then we match a group of 1 or more dashes and precede it with a space.
Do it in three steps:
first replace '/---+/' by '#minus#' (or some other recognisable placeholder)
then replace all /[- ]+/ by ' ' (a single blank)
replace all'#minus#' by ' - '
Just replace all "--" Occurence, and you should get only "-" after that
Have you tried str_replace("---","-",$string)?. This way if there are three minus in sequence, they will be replaced by only one.

How to split a string into two parts then join them in reverse order as a new string?

This is an example:
$str="this is string 1 / 4w";
$str=preg_replace(?); var_dump($str);
I want to capture 1 / 4w in this string and move this portion to the begin of string.
Result: 1/4W this is string
Just give me the variable that contains the capture.
The last portion 1 / 4W may be different.
e.g. 1 / 4w can be 1/ 16W , 1 /2W , 1W , or 2w
The character W may be an upper case or a lower case.
Use capture group if you want to capture substring:
$str = "this is string 1 / 4w"; // "1 / 4w" can be 1/ 16W, 1 /2W, 1W, 2w
$str = preg_replace('~^(.*?)(\d+(?:\s*/\s*\d+)?w)~i', "$2 $1", $str);
var_dump($str);
Without seeing some different sample inputs, it seems as though there are no numbers in the first substring. For this reason, I use a negated character class to capture the first substring, leave out the delimiting space, and then capture the rest of the string as the second substring. This makes my pattern very efficient (6x faster than Toto's and with no linger white-space characters).
Pattern Demo
Code:
$str="this is string 1 / 4w";
$str=preg_replace('/([^\d]+) (.*)/',"$2 $1",$str);
var_export($str);
Output:
'1 / 4w this is string'

Split address street name house number and room number

I need split address: Main Str. 202-52 into
street=Main Str.
house No.=202
room No.=52
I tried to use this:
$data['address'] = "Main Str. 202-52";
$data['street'] = explode(" ", $data['address']);
$data['building'] = explode("-", $data['street'][0]);
It is working when street name one word. How split address where street name have several words.
I tried $data['street'] = preg_split('/[0-9]/', $data['address']);But getting only street name...
You may use a regular expression like
/^(.*)\s(\d+)\W+(\d+)$/
if you need all up to the last whitespace into group 1, the next digits into Group 2 and the last digits into Group 3. \W+ matches 1+ chars other than word chars, so it matches - and more. If you have a - there, just use the hyphen instead of \W+.
See the regex demo and a PHP demo:
$s = "Main Str. 202-52";
if (preg_match('~^(.*)\s(\d+)\W+(\d+)$~', $s, $m)) {
echo $m[1] . "\n"; // Main Str.
echo $m[2] . "\n"; // 202
echo $m[3]; // 52
}
Pattern details:
^ - start of string
(.*) - Group 1 capturing any 0+ chars other than line break chars as many as possible up to the last....
\s - whitespace, followed with...
(\d+) - Group 2: one or more digits
\W+ - 1+ non-word chars
(\d+) - Group 3: one or more digits
$ - end of string.
Also, note that in case the last part can be optional, wrap the \W+(\d+) with an optional capturing group (i.e. (?:...)?, (?:\W+(\d+))?).

Categories