simple preg_replace() not working right for me :/ - php

$str = "{Controller}/{Action}";
$str = preg_replace("/\//","\\/",$str);
$str = preg_replace("/(\{\w+\})\\/(\{\w+\})/","\\1 slash \\2",$str);
echo $str;
So the third line doesn't do anything for me, could anyone say where i was wrong? It works if i put something else instead of \/
thanks in advance;)

This will work:
$str = "{Controller}/{Action}";
$str = preg_replace('#(\{\w+\})/(\{\w+\})#', '\1 slash \2', $str);
echo $str;
Output: {Controller} slash {Action}
Remarks:
You should use single quotes to reduce the need for escaping and therefore much better readability.
You also should consider using another delimiter if you are matching literal slashes (eg #, but anything works)

Related

PHP Regex replace all instances of a character in similar strings

I have a file that contains a collection strings. All of the strings begin with the same set of characters and end with the same character. I need to find all of the strings that match a certain pattern, and then remove particular characters from them before saving the file. Each string looks like this:
Data_*: " ... "
where Data_ is the same for each string, the asterisk is an incrementing integer that is either two or three digits, and the colon and the double quotation marks are the same for each string. The ... is completely different in every string and it's the part of each I need to work with. I need to remove all double quotation marks from the ... , preserving the enclosing double quotation marks. I don't need to replace them, just remove them.
So for example, I need this...
Data_83: "He said, "Yes!" to the question"
to become this...
Data_83: "He said, Yes! to the question"
I am familiar with PHP and would like to use this. I know how to do something like...
<?php
$filename = 'path/to/file';
$content = file_get_contents($filename);
$new_content = str_replace('"', '', $content);
file_put_contents($filename, $new_content);
And I'm pretty sure a regular expression will be what I'm wanting to use to find the strings and remove the extra double quotation marks. But I'm very new to regular expressions and need some help here.
EDIT:
I should have mentioned, the file is a PHP file containing an object. It looks a bit like this:
<?php
$thing = {
Data_83: "He said, "Yes!" to the question",
Data_84: "Another string with "unwanted" quotes"
}
You may use preg_replace_callback with a regex like
'~^(\h*Data_\d{2,}:\h*")(.*)"~m'
Note that you may make it safer if you specify an optional , at the end of the line: '~^(\h*Data_\d{2,}:\h*")(.*)",?\h*$~m' but you might need to introduce another capturing group then (around ,?\h*, and then append $m[3] in the preg_replace_callback callback function).
Details
^ - start of the line (m is a multiline modifier)
(\h*Data_\d{2,}:\h*") - Group 1 ($m[1]):
\h* - 0+ horizontal whitespaces
Data_ - Data_ substring
\d{2,} - 2 or more digits
: - a colon
\h* - 0+ horizontal whitespaces
" - double quote
(.*) - Group 2 ($m[2]): any 0+ chars other than line break chars, as many as possible, up to the last...
" - double quote (on a line).
The $m represents the whole match object, and you only need to remove the " inside $m[2], the second capture.
See the PHP demo:
preg_replace_callback('~^(\h*Data_\d{2,}:\h*")(.*)"~m', function($m) {
return $m[1] . str_replace('"', '', $m[2]) . '"';
}, $content);
Not as elegant but you could create a UDF:
function RemoveNestedQuotes($string)
{
$firstPart = explode(":", $string)[0];
preg_match('/"(.*)"/', $string, $matches, PREG_OFFSET_CAPTURE);
$tmpString = $matches[1][0];
return $firstPart . ': "' . preg_replace('/"/', '', $tmpString) . '"';
}
example:
$string = 'Data_83: "He said, "Yes!" to the question"';
echo RemoveNestedQuotes($string);
// Data_83: "He said, Yes! to the question"
One more step after str_replace with implode and explode. You can just do it like this.
<?php
$string = 'Data_83: "He said, "Yes!" to the question"';
$string = str_replace('"', '', $string);
echo $string =implode(': "',explode(': ',$string)).'"';
?>
Demo : https://eval.in/912466
Program Output
Data_83: "He said, Yes! to the question"
Just to replace " quotes
<?php
$string = 'Data_83: "He said, "Yes!" to the question"';
echo preg_replace('/"/', '', $string);
?>
Demo : https://eval.in/912457
The way I see it, you don't need to make any preg_replace_callback() calls or a convoluted run of explosions and replacements. You merely need to disqualify the 2 double quotes that you wish to retain and match the rest for removal.
Code: (Demo)
$string = 'Data_83: "He said, "Yes!" to the question",
Data_184: "He said, "WTF!" to the question"';
echo preg_replace('/^[^"]+"(*SKIP)(*FAIL)|"(?!,\R|$)/m','',$string);
Output:
Data_83: "He said, Yes! to the question",
Data_184: "He said, WTF! to the question"
Pattern Demo
/^[^"]+"(*SKIP)(*FAIL)|"(?!,?$)/m
This pattern says:
match from the start of each line until you reach the first double quote, then DISQUALIFY it.
then after the |, match all double quotes that are not optionally followed by a comma then the end of line.
While this pattern worked on regex101 with my sample input, when I transferred it to the php sandbox to whack together a demo, I needed to add \R to maintain accuracy. You can test to see which is appropriate for your server/environment.

How to add single quote with Regex php arrays

For From
$data[ContactInfos][ContactInfo][Addresses]
to
$data['ContactInfos']['ContactInfo']['Addresses']
Try the following regex(Demo):
(?<=\[)|(?=\])
PHP(Demo):
preg_replace('/(?<=\[)|(?=\])/', "'", $str);
With this
preg_replace('/\[([^\]]+)\]/', "['\1']", $input);
Try it here
https://regex101.com/r/YTIOWY/1
If you have mixed string - with and without quote, regex must be a little sophysticated
$str = '$data[\'ContactInfos\'][ContactInfo]["Addresses"]';
$str = preg_replace('/(?<=\[)(?!(\'|\"))|(?<!(\'|\"))(?=\])/', "'", $str);
// result = $data['ContactInfos']['ContactInfo']["Addresses"]
demo
The first rule of regex: "Don't use regex unless you have to."
This question doesn't require regex and the function call is not prohibitively convoluted. Search for square brackets, and write a single quote on their "inner" side.
Code (Demo)
$string='$data[ContactInfos][ContactInfo][Addresses]';
echo str_replace(['[',']'],["['","']"],$string);
Output:
$data['ContactInfos']['ContactInfo']['Addresses']

How to replace backslashes with forward slashes without changing the content of the link

There is an old question from 2011 but with a wrong answer.
Maybe now someone can give a better answer. The question was: How can we replace the backslashes with forward slashes from this variable-link:
$str = "http://www.domain.com/data/images\flags/en.gif";
The wrong answer was that:
echo $str = str_replace('\\', '/', $str);
And it was wrong because the result of that code changes the content of the link. (http://www.domain.com/data/imageslags/en.gif)
It finds not only the backslash but the letter f after that and it deletes them because \f means "formfeed (hex 0C)". So how can we avoid this wrong replacement?
The Code is here
i hope this helps you
$str = "http://www.domain.com/data/images\flags/en.gif";
echo $str = str_replace('lags', "/flags", $str);
You can use addcslashes but you'll have to specify each possible escaped character that could occur in $str
$str = "http://www.domain.com/data/images\flags/en.gif";
$escaped = str_replace("\\","/",addcslashes($str,"\f\r\n\t"));
echo $escaped; // result is 'http://www.domain.com/data/images/flags/en.gif'

replacing a string with preg_replace

I have a URL like this:
http://Example.com/mobile-ds-cams/mobile-gg-cams/ddd-webcams
Example:
$pattern = '/http://Example.com/(\w+)/(\w+)/(\w+)/i';
$replacement="http://Example.com/$2/$3";
$appUrl= preg_replace($pattern, $replacement, $appUrl);
What I want to achieve is this
http://Example.com/mobile-gg-cams/ddd-webcams
I am trying to keep 2 "sub-URLs" instead of 3. but it doesn't work..why?
You need to escape your forward-slashes within the pattern, or use different pattern delimiters.
$pattern = '/http:\/\/Example\.com\/(\w+)\/(\w+)\/(\w+)/i';
$pattern = '#http://Example\.com/(\w+)/(\w+)/(\w+)#i';
It doesn't work correctly because your expression contains characters with special meaning in a regex that have not been properly quoted.
To be 100% certain, use preg_quote like this:
$url = 'http://Example.com/'
$pattern = preg_quote($url.'{word}/{word}/{word}', '/');
$pattern = str_replace($pattern, '{word}', '(\w+)');
$pattern = "/$pattern/i";
$replacement = $url.'$2/$3';
$appUrl= preg_replace($pattern, $replacement, $appUrl);
Otherwise, it's simply too easy to get things wrong. For example, all of the other answers currently posted here get it wrong because they do not properly escape the . in Example.com. You can test this yourself if you feed them a string like e.g. http://Example!com, where ! can be any character you like.
Additionally, you are using strings such as $2 inside a double-quoted string literal, which is not a good idea in PHP because IMHO it's easy to get carried away. Better make that singly quoted and be safe.
Escape the slashes like this:
$pattern = '/http:\/\/Example.com\/(\w+)\/(\w+)\/(\w+)/i';
$replacement="http://Example.com/$2/$3";
$appUrl= preg_replace($pattern, $replacement, $appUrl);

PHP Regex to trim a file

I need to go through a huge file and remove all strings that appear within <> and (. .).
Between those brackets there can be anything: text, numbers, whitespaces etc.
Eg:
< there will be some random 123 text here >
I could read the file and use str_replace to trim out all those parts, but what I don't know is how can I use regex to pick up the string enclosed in the brackets.
Here's what I want to do:
$line = "this should stay <this should not>";
//$trim = do something here using regex so $trim = "<this should not>"
$line = str_replace($trim,"",$line);
PS:
The data might be spread across lines:
this should stay
(. this
should
not .)
$nlstr = "{{{".uniqid()."}}}"
$str = str_replace("\n",$nlstr,$str);
$str = preg_replace("/<[^>]*>/","",$str);
$str = preg_replace("/\(\.([^.)]+[.)]?)*\.\)/","",$str);
$str = str_replace($nlstr,"\n",$str);
EDIT: edited to enable newlines through a very hackish manner.
EDIT: forgot to escape the fullstops and brackets where necessary.
Use the non-greedy quantifier .*? to match a < with the closest >. Use the s modifier to take care of newlines within your string:
<?php
$str = 'this should stay < this should not >
this should stay (.this should not.)
this should stay < this
should
not >
this should stay (.this
should
not.)';
$str = preg_replace('#<.*?>#s', '', $str);
$str = preg_replace('#\(\..*?\.\)#s', '', $str);
echo $str;
?>
Output:
this should stay
this should stay
this should stay
this should stay
If you don't have to worry about nesting (\(\..*?\.\))|(<(.*?>) will do the job

Categories