Some confusion with preg_replace - php

I am very confused with preg_replace, I have this string and I would like to change ONLY the number before the _
$string = 'string/1_491107.jpg';
$newstring = preg_replace('#([0-9]+)_#', '666', $string);
But then I get "string/666491107.jpg" instead "string/666_491107.jpg"
Thanks

What you're doing here is matching the numbers in the parenthesis as $1 in your replacement. You don't actually say "only the stuff in parenthesises should be replaced".
You could do it like this:
$string = 'string/1_491107.jpg';
$newstring = preg_replace('#[0-9]+_#', '666_', $string);
or you could use a positive lookahead (only match a number sequence followed by an underscore, but don't include the underscore in the match):
$string = 'string/1_491107.jpg';
$newstring = preg_replace('#[0-9]+(?=_)#', '666', $string);
Regex 101 demo

You've got the underscore as part of the text to be replaced; so you also need to include it in the replacement:
$string = 'string/1_491107.jpg';
$newstring = preg_replace('#([0-9]+)_#', '666_', $string);

Related

preg_replace with () characters

I want to use preg_replace to clean a string but I want to contine with this character () - Parentheses
I'm using this code
$string = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string);
$string = preg_replace('/[^\p{Latin}\d ]/u', '', $string);
I want to remove everything except the parentheses letters and numbers
If I understand you correctly, use:
/[^\p{Latin}0-9()]/u
That will match anything that is not parentheses, letters or numbers.
So the full code:
$string = preg_replace('/[^\p{Latin}0-9()]/u', '', $string);

Regular Expression to replace a bracket with word in front when not preceded by word

I am facing problem with a regular expression.
I have a string like ('A'&'B')
Now I want to convert it to CONCAT('A'&'B') which is simple and I have done using
str_replace("(", "CONCAT(", $subject)
But I want to replace "(" to "CONCAT(" if the string doesn't have prior string "extract_json_value".
So I don't want to replace extract_json_value('A'&'B') to extract_json_valueCONCAT('A'&'B') but it will stay as it is extract_json_value('A'&'B').
You can expand your regex with a negative lookbehind:
(?<!extract_json_value)\(
Here is a regex demo!
You could use strpos to do this.
if (strpos($subject, '(') === 0) {
$subject = str_replace('(', 'CONCAT(', $subject);
}
If your string contains other text you can use preg_replace() and use a word boundary \B for this.
$subject = preg_replace('/\B\(/', 'CONCAT(', $subject);
You can use negative lookbehind in order to match a group not preceded by a string.
First, let's have a regexp matching all strings but those containing "extract_json_value":
(?<!extract_json_value).*
Now, let's use preg_replace
$string = "extract_json_value('A'&'B')";
$pattern = '/^(?<!extract_json_value)(\(.+\))$/';
$replacement = 'CONCAT\1';
echo preg_replace($pattern, $replacement, $string);
// prints out "extract_json_value('A'&'B')"
It works too with
$string = "('A'&'B')";
...
// prints out "CONCAT('A'&'B')"
However, it does not work with
$string = "hello('A'&'B')";
...
// prints out "helloCONCAT('A'&'B')"
So, continue with a preg_replace_callback:
http://php.net/manual/fr/function.preg-replace-callback.php

preg_replace only substring before defined char

I'm trying to replace chars not [A-Z] and before the # inside a string. So this
AreplacehereZ#domain.tld
needs to become:
A***********Z#domain.tld
I tried with:
$string = 'AreplacehereZ#domain.tld';
$pattern = '/(?<!#)[^A-Z#\.]/';
$replacement = '*';
$replace = preg_replace($pattern, $replacement, $tring);
but the result is
'A***********Z#d*****.***'
So I can't find the way how to avoid the replacement of #domain.tld by only using preg_replace().
domain.tld can be anything so I can't use (?<!#domain.tld) in the $pattern var.
You can just assert that from the current position, match [^A-Z], then make sure you can consume any number of characters but still hit the #:
$pattern = '/[^A-Z](?=[^#]*#)/';
Produces:
A***********Z#domain.tld

how to remove last occurance of underscore in string

I have a string that contains many underscores followed by words ex: "Field_4_txtbox" I need to find the last underscore in the string and remove everything following it(including the "_"), so it would return to me "Field_4" but I need this to work for different length ending strings. So I can't just trim a fixed length.
I know I can do an If statement that checks for certain endings like
if(strstr($key,'chkbox')) {
$string= rtrim($key, '_chkbox');
}
but I would like to do this in one go with a regex pattern, how can I accomplish this?
The matching regex would be:
/_[^_]*$/
Just replace that with '':
preg_replace( '/_[^_]*$/', '', your_string );
There is no need to use an extremly costly regex, a simple strrpos() would do the job:
$string=substr($key,0,strrpos($key,"_"));
strrpos — Find the position of the last occurrence of a substring in a string
You can also just use explode():
$string = 'Field_4_txtbox';
$temp = explode('_', strrev($string), 2);
$string = strrev($temp[1]);
echo $string;
As of PHP 5.4+
$string = 'Field_4_txtbox';
$string = strrev(explode('_', strrev($string), 2)[1]);
echo $string;

Replace all characters in string apart from PHP

I have a string Trade Card Catalogue 1988 Edition I wish to remove everything apart from 1988.
I could have an array of all letters and do a str_replace and trim, but I wondered if this was a better solution?
$string = 'Trade Card Catalogue 1988 Edition';
$letters = array('a','b','c'....'x','y','z');
$string = str_to_lower($string);
$string = str_replace($letters, '', $string);
$string = trim($string);
Thanks in advance
Regular expression?
So assuming you want the number (and not the 4th word or something like that):
$str = preg_replace('#\D#', '', $str);
\D means every character that is not a digit. The same as [^0-9].
If there could be more numbers but you only want to get a four digit number (a year), this will also work (but obviously fails if you there are several four digit numbers and you want to get a specific one) :
$str = preg_replace('#.*?(\d{4,4}).*#', '\1', $str);
You can actually just pass the entire set of characters to be trimmed as a parameter to trim:
$string = trim($string, 'abc...zABC...Z ' /* don't forget the space */);

Categories