preg_match dose not work correctly in php - php

all,
I am using preg_match to filter some data, and it is strange that, it dose not work correctly. I am new to regex, and I used a php live regex website to check my regex, which works correctly. So I have no idea what is wrong here.
I would like to have preg_match to find something like "a\_b" in the $string:
$string="aaa\_bbb:ccc"
if(preg_match("/[a-zA-Z]\\_[a-zA-Z]/", $string)){
$snew = str_replace('\_', "_", $string);
}
But it is strange that even I have a $string like in this example above, the result of preg_match is 0. But when I change it to
preg_match("/\\_[a-zA-Z]/", $string)
It works fine and return 1. But of course that is not what I want. Any idea?
Thanks very much~

You don't really need the preg_match at all, from what I can see.
However the problem you're having with it is to do with escaping.
You have this: "/[a-zA-Z]\\_[a-zA-Z]/"
You've correctly identified that the backslash needs to be escaped, however, you've missed a subtle issue:
Regular expressions in PHP are strings. This means that you need to escape it as a string as well as a regular expression. In effect, this means that to correctly escape a backslash so it is matched as an actual backslash character in your pattern, you actually need to have four backslashes.
"/[a-zA-Z]\\\\_[a-zA-Z]/"
It's not pretty, but that's how it is.
Hope that helps.

use:
if(preg_match("/[a-zA-Z]\\\\_[a-zA-Z]/", $string))
instead

You don't need the preg_match altogether, instead just do a replace using this regex:
/([a-zA-Z])\\\\_([a-zA-Z])/
and then replace with $1_$2, like this:
$result = preg_replace("/([a-zA-Z])\\\\_([a-zA-Z])/", "$1_$2$, $string);

Related

PHP preg_replace pattern only seems to work if its wrong?

I have a string that looks like this
../Clean_Smarty_Projekt/tpl/templates_c\.
../Clean_Smarty_Projekt/tpl/templates_c\..
I want to replace ../, \. and \.. with a regulare expression.
Before, I did this like this:
$result = str_replace(array("../","\..","\."),"",$str);
And there it (pattern) has to be in this order because changing it makes the output a little buggy. So I decided to use a regular expression.
Now I came up with this pattern
$result = preg_replace('/(\.\.\/)|(\\[\.]{1,2})/',"",$str);
What actually returns only empty strings...
Reason: (\\[\.]{1,2})
In Regex101 its all ok. (Took me a couple of minutes to realize that I don't need the /g in preg_replace)
If I use this pattern in preg_replace I have to do (\\\\[\.]{1,2}) to get it to work. But that's obviously wrong because im not searching for two slashes.
Of course I know the escaping rulse (escaping slashes).
Why doesn't this match correctly ?
I suggest you to use a different php delimiter. Within the / delimiter, you need to use three \\\ or four \\\\ backslashes to match a single backslash.
$string = '../Clean_Smarty_Projekt/tpl/templates_c\.'."\n".'../Clean_Smarty_Projekt/tpl/templates_c\..';
echo preg_replace('~\.\./|\\\.{1,2}~', '', $string)
Output:
Clean_Smarty_Projekt/tpl/templates_c
Clean_Smarty_Projekt/tpl/templates_c

Need to match multiple backslahes in a PHP regex

I'm trying to match 4 backslahes using preg_match.
preg_match('/\\\\\\\\/',$subject) works fine, but preg_match('/\\{4}/',$subject) doesn't.
Perhaps I'm using {} incorrectly. Could anyone advise?
Ok I got it: Two backslashes mean you want one backslash in your string: So for the regex it looks like this: /\{4}/ Which means you want to escape the {
What you need here is:
preg_match('/\\\\{4}/', $subject);
That looks for the regex like this: /\\{4}/ and works properly.
Regex is the wrong tool when you're looking for a literal string.
strpos($subject, str_repeat("\\",4)) !== false
Use this:
preg_match('/(?:\\\\){2}/',$subject, $m);
It matches 4 backslashes.

Problem using regex to remove number formatting in PHP

I'm having this issue with a regular expression in PHP that I can't seem to crack. I've spent hours searching to find out how to get it to work, but nothing seems to have the desired effect.
I have a file that contains lines similar to the one below:
Total','"127','004"','"118','116"','"129','754"','"126','184"','"129','778"','"128','341"','"127','477"','0','0','0','0','0','0
These lines are inserted into INSERT queries. The problem is that values like "127','004" are actually supposed to be 127,004, or without any formatting: 127004. The latter is the actual value I need to insert into the database table, so I figured I'd use preg_replace() to detect values like "127','004" and replace them with 127004.
I played around with a Regular Expression designer and found that I could use the following to get my desired results:
Regular Expression
"(\d+)','(\d{3})"
Replace Expression
$1$2
The line on the top of this post would end up like this: (which is what I am after)
Total','127004','118116','129754','126184','129778','128341','127477','0','0','0','0','0','0
This, however, does not work in PHP. Nothing is being replaced at all.
The code I am using is:
$line = preg_replace("\"(\d+)','(\d{3})\"", '$1$2', $line);
Any help would be greatly appreciated!
There are no delimiters in your regex. Delimiters are required in order for PHP to know what is the pattern to match and what is a pattern modifier (e.g. i - case-insensitive, U - ungreedy, ...). Use a character that doesn't occur in your pattern, typically you'll see a slash '/' used.
Try this:
$line = preg_replace("/\"(\d+)','(\d{3})\"/", '$1$2', $line);
You forgot to wrap your regular expression in front-slashes. Try this instead:
"/\"(\d+)','(\d{3})\"/"
use preg_replace("#\"(\d+)','(\d+)\"#", '$1$2', $s); instead of yours

regex back-reference not working in PHP PCRE

I want to match matching tags like <tag>...</tag>. I tried the regex
~<([^>]+)>.*?</\1>~
but this fails. The expression worked when I used the exact text inside the angle brackets, i.e,
~<(tag)>.*?</tag>~
works, but even
~<(tag)>.*?</\1>~
fails.
I'm assuming that the back reference is not working here.
Can someone help me out please. Thanks
PS: I'm not using this to parse HTML. I know I shouldn't.
You didn't show your PHP code, but I surmise you have your regex in double quotes. If so then the backreference \1 actually is converted into an ASCII character ☺ before it reaches PCRE. (All \123 sequences are interpreted as C-string octal escapes there.)
It worked for me...
$str = '<a></a>';
var_dump(preg_match('~<([^>]+)>.*?</\1>~', $str)); // int(1)
CodePad.
Also, have you considered an XML parser? Otherwise it won't like a piece of HTML like this...
<a title="Is 4 > 6?"></a>
CodePad.
Apart from the fact that it's not always a good idea to try and match markup languages using regex, your regex looks OK. Maybe you're using it wrong?
if (preg_match('~<([^>]+)>.*?</\1>~', $subject, $regs)) {
$result = $regs[0];
} else {
$result = "";
}
should work.
Use single quotes in the pattern
preg_match_all('/(sens|respons)e and \1ibility/', "sense and sensibility", $matches);
print_r($matches);

PHP: Preg replace string with nothing

I'm new to preg_replace() and I've been trying to get this to work, I couldn't so StackOverflow is my last chance.
I have a string with a few of these:
('pm_IDHERE', 'NameHere');">
I want it to be replaced with nothing, so it would require 2 wildcards for NameHere and pm_IDHERE.
But I've tried it and failed myself, so could someone give me the right code please, and thanks :)
Update:
You are almost there, you just have to make the replacement an empty string and escape the parenthesis properly, otherwise they will be treated as capture group (which you don't need btw):
$str = preg_replace("#\('pm_.+?', '.*?'\);#si", "", $str);
You probably also don't need the modifiers s and i but that is up to you.
Old answer:
Probably str_replace() is sufficient:
$str = "Some string that contains pm_IDHERE and NameHere";
$str = str_replace(array('pm_IDHERE', 'NameHere'), '', $str);
If this is not what you mean and pm_IDHERE is actually something like pm_1564 then yes, you probably need regular expressions for that. But if NameHere has no actual pattern or structure, you cannot replace it with regular expression.
And you definitely have to explain better what kind of string you have and what kind of string you have want to replace.

Categories