preg_match a back slash - php

$pattern = '/\\\p\\\/';
if (preg_match($pattern, "\p\")) {
echo "Correct";
} else {
echo "Incorrect";
}
I don't understand the first \\\p.
Why \\p does not work?

Your pattern is wrong. pattern \\p\\ matches the string \p\. But \\\p\\\ doesn't matches anything.
DEMO
If you want to match the string \\p\\, your pattern should be \\\\p\\\\.
DEMO

Note that "\p\" is not a valid string:
The final \" escapes the quote, so that the string is not terminated
The \p matches a literal p character, which is not what you intended
If you want to say \p\ in a string, you have to write it like this: "\\p\\"
To match \p\, use:
$regex = '~\\\\p\\\\~';
echo (preg_match($regex,"\\p\\")) ? "Matches" : "Doesn't Match";
See the output at the bottom of the online demo.

The problem here is that both strings and regular expressions use escape characters and they need to be doubled in order to effect the intended behaviour.
So, in this case you need four backslashes in the regular expression and two of them in the search string:
if (preg_match('/\\\\p\\\\/', '\\p\\')) {
echo "Hurray!\n";
}
The reason why '/\\\p\\\/' works is because \p and \/ have no special meaning in a single quoted string and so the backslash is printed verbatim. In other words, PHP corrects your string to have the correct meaning; that said, you should use the correct number of escape characters.
Btw, "\\p\" is just plain wrong and will cause a parse error; I'm going to assume that this was a typo.

Related

PHP Regex Strip Away All Emojis

I am trying to strip away all non-allowed characters from a string using regex. Here is my current php code
$input = "👮";
$pattern = "[a-zA-Z0-9_ !##$%^&*();\\\/|<>\"'+\-.,:?=]";
$message = preg_replace($pattern,"",$input);
if (empty($message)) {
echo "The string is empty";
}
else {
echo $message;
}
The emoji gets printed out when I run this when I want it to print out "The string is empty.".
When I put my regex code into http://regexr.com/ it shows that the emoji is not matching, but when I run the code it gets printed out. Any suggestions?
This pattern should do the trick :
$filteredString = preg_replace('/([^-\p{L}\x00-\x7F]+)/u', '', $rawString);
Some sequences are quite rare, so let's explain them:
\p{L} matches any kind of letter from any language
\x00-\x7F a single character in the range between (index 0) and (index 127) (case sensitive)
the u modifier who turns on additional functionality of PCRE that is incompatible with Perl. Pattern and subject strings are treated as UTF-8.
Your pattern is incorrect. If you want to strip away all the characters that are not in the list provided, then you have to use a negating character class: [^...]. Also, currently, [ and ] are being used as delimiters, which means, the pattern isn't seen as a character class.
The pattern should be:
$pattern = "~[^a-zA-Z0-9_ !##$%^&*();\\\/|<>\"'+.,:?=-]~";
This should now strip away the emoji and print your message.

Regex is failing to capture values inside [...][...]

I am trying to change color of a text in my string :
my string :
$message="I have a [red][car]";
I want to capture the values inside the first [...] and second [...] and then use it in
<b style='color:color'>car</b>
to change the text color according to the value of first [...]
So far I have :
echo preg_replace("/\[([^\]]+)\]\[([^\]+])\]/i","<b style='color:$1'>$2</b>",$message);
But it's not working, the orignal string is returned as output. I don't know where my regex failed.
Please help!
The corrected regex is:
'/\[([^\]]+)]\[([^\]]+)]/'
See regex demo
Note that you do not have to escape ] outside the character class and no need in /i modifier as there are not letters in your pattern. Also, to properly escape special regex characters, you either need to double escapes in the double quoted string, or use a single quoted string.
IDEONE demo:
$message="I have a [red][car]";
echo preg_replace('/\[([^\]]+)]\[([^\]]+)]/',"<b style='color:$1'>$2</b>",$message);
// => I have a <b style='color:red'>car</b>
$message="I have a [red][car]";
echo preg_replace("/[^\[]+\[([^\]]+)\]\[([^\]]+)\]/i","<b style='color:$1'>$2</b>",$message);

PHP regex to allow newline didn't work

PHP preg_match to accept new line
I want to pass every post/string through PHP preg_match function. I want to accept all the alpha-numerics and some special characters. Help me edit my syntax to allow newline. As the users fill textarea and press enter. Following syntax does not allow new line.
Please feedback whether following special characters are properly done or not
*/_:,.?#;-*
if (preg_match("/^[0-9a-zA-Z \/_:,.?#;-]+$/", $string)) {
echo 'good';
else {
echo 'bad';
}
You were almost there!
The DOTALL modifier mentioned by others is irrelevant to your regex.
To allow new lines, we just add \r\n to your character class. Your code becomes:
if (preg_match("/^[\r\n0-9a-zA-Z \/_:,.?#;-]+$/", $string)) {
echo 'good';
else {
echo 'bad';
}
Note that this test and the regex can be written in a tidier way:
echo (preg_match("~^[\r\n\w /:,.?#;-]+$~",$string))? "***Good!***" : "Bad!";
See the result of the online demo at the bottom.
\w matches letters, digits and underscores, so we can get rid of them in the character class
Changing the delimiter to a ~ allows you to use a / slash without escaping it (you need to escape delimiters)
it's always safe to add backslash to any non-alphanumeric characters so:
/^[0-9a-zA-Z \/\_\:\,\.\?\#\;\-]+$/
Also use character classes:
/^[[:alnum:] \/\_\:\,\.\?\#\;\-]+$/
oh about the new lines:
/^[[:alnum:] \r\n\/\_\:\,\.\?\#\;\-]+$/
to be able to do that string ^ (also, it'll be easier/safer to use single quotes)
'/^[[:alnum:] \\r\\n\/\_\:\,\.\?\#\;\-]+$/'
You can use an alternation to factor in the newlines:
/^(?:[0-9a-zA-Z \/_:,.?#;-]|\r?\n)+$/
Btw, you can shorten the expression a bit by replacing [A-Za-z0-9_] with [\w\d]:
/^(?:[\w\d \/:,.?#;-]|\r?\n)+$/
So:
if (preg_match('/^(?:[\w\d \/:,.?#;-]|\r?\n)+$/', $string)) {
echo "good";
} else {
echo "bad";
}

preg_replace PHP not working?

Why doesn't preg_replace return anything in this scenario? I've been trying to figure it out all night.
Here is the text contained within $postContent:
Test this. Here is a quote: [Quote]1[/Quote] Quote is now over.
Here is my code:
echo "Test I'm Here!!!";
$startQuotePos = strpos($postContent,'[Quote]')+7;
$endQuotePos = strpos($postContent,'[/Quote]');
$postStrLength = strlen($postContent);
$quotePostID = substr($postContent,$startQuotePos,($endQuotePos-$postStrLength));
$quotePattern = '[Quote]'.$quotePostID.'[/Quote]';
$newPCAQ = preg_replace($quotePattern,$quotePostID,$postContent);
echo "<br />$startQuotePos<br />$endQuotePos<br />$quotePostID<br />Qpattern:$quotePattern<br />PCAQ: $newPCAQ<br />";
This is my results:
Test I'm Here!!!
35
36
1
Qpattern:[Quote]1[/Quote]
PCAQ:
For preg_replace(), "[Quote]" matches a single character that is one of the following: q, u, o, t, or e.
If you want that preg_replace() finds the literal "[Quote]", you need to escape it as "\[Quote\]". preg_quote() is the function you should use: preg_quote("[Quote]").
Your code is also wrong because a regular expression is expected to start with a delimiter. In the preg_replace() call I am showing at the end of my answer, that is #, but you could use another character, as long as it doesn't appear in the regular expression, and it is used also at the end of the regular expression. (In my case, # is followed by a pattern modifier, and pattern modifiers are the only characters allowed after the pattern delimiter.)
If you are going to use preg_replace(), it doesn't make sense that you first find where "[Quote]" is. I would rather use the following code:
$newPCAQ = preg_replace('#\[Quote\](.+?)\[/Quote\]#i', '\1', $postContent);
I will explain the regular expression I am using:
The final '#i' is saying to preg_replace() to ignore the difference between lowercase, and uppercase characters; the string could contain "[QuOte]234[/QuOTE]", and that substring would match the regular expression the same.
I use a question mark in "(.+?)" to avoid ".+" is too greedy, and matches too much characters. without it, the regular expression could include in a single match a substring like "[Quote]234[/Quote] Other text [Quote]475[/Quote]" while this should be matched as two substrings: "[Quote]234[/Quote]", and "[Quote]475[/Quote]".
The '\1' string I am using as replacement string is saying to preg_replace() to use the string matched from the sub-group "(.+?)" as replacement. In other words, the call to preg_replace() is removing "[Quote]", and "[/Quote]" surrounding other text. (It doesn't replace "[/Quote]" that doesn't match with "[Quote]", such as in "[/Quote] Other text [Quote]".)
your regex must start & end with '/':
$quotePattern = '/[Quote]'.$quotePostID.'[/Quote]/';
The reason you don't see anything for the return value of preg_replace is because it has returned NULL (see the manual link for details). This is what preg_replace returns when an error occurs, which is what happened in your situation. The string value of NULL is a zero-length string. You can see this by using var_dump instead, which will tell you that preg_replace returned NULL.
Your regular expression is invalid and as such PHP will throw an E_WARNING level error of Warning: preg_replace(): Unknown modifier '['
There are a couple of reason for this. First, you need to specify an opening and closing delimiter for you regular expression as preg_* functions use PCRE style regular expression. Second, you want to also consider using preg_quote on your patter (sans the delimiter) to ensure it is escaped properly.
$postContent = "Test this. Here is a quote: [Quote]1[/Quote] Quote is now over.";
/* Specify a delimiter for your regular expression */
$delimiter = '#';
$startQuotePos = strpos($postContent,'[Quote]')+7;
$endQuotePos = strpos($postContent,'[/Quote]');
$postStrLength = strlen($postContent);
$quotePostID = substr($postContent,$startQuotePos,($endQuotePos-$postStrLength));
/* Make sure you use the delimiter in your pattern and escape it properly */
$quotePattern = $delimiter . preg_quote("[Quote]{$quotePostID}[/Quote]", $delimiter) . $delimiter;
$newPCAQ = preg_replace($quotePattern,$quotePostID,$postContent);
echo "<br />$startQuotePos<br />$endQuotePos<br />$quotePostID<br />Qpattern:$quotePattern<br />PCAQ: $newPCAQ<br />";
The output will be:
35
36
1
Qpattern:#[Quote]1[/Quote]#
PCAQ: Test this. Here is a quote: 1 Quote is now over.

regex with special characters?

i am looking for a regex that can contain special chracters like / \ . ' "
in short i would like a regex that can match the following:
may contain lowercase
may contain uppercase
may contain a number
may contain space
may contain / \ . ' "
i am making a php script to check if a certain string have the above or not, like a validation check.
The regular expression you are looking for is
^[a-z A-Z0-9\/\\.'"]+$
Remember if you are using PHP you need to use \ to escape the backslashes and the quotation mark you use to encapsulate the string.
In PHP using preg_match it should look like this:
preg_match("/^[a-z A-Z0-9\\/\\\\.'\"]+$/",$value);
This is a good place to find the regular expressions you might want to use.
http://regexpal.com/
You can always escape them by appending a \ in front of the special characters.
try this:
preg_match("/[A-Za-z0-9\/\\.'\"]/", ...)
NikoRoberts is 100% correct.
I would only add the following suggestion: When creating a PHP regex pattern string, always use: single-quotes. There are far fewer chars which need to be escaped (i.e. only the single quote and the backslash itself needs to be escaped (and the backslash only needs to be escaped if it appears at the end of the string)).
When dealing with backslash soup, it helps to print out the (interpreted) regex string. This shows you exactly what is being presented to the regex engine.
Also, a "number" might have an optional sign? Yes? Here is my solution (in the form of a tested script):
<?php // test.php 20110311_1400
$data_good = 'abcdefghijklmnopqrstuvwxyzABCDE'.
'FGHIJKLMNOPQRSTUVWXYZ0123456789+- /\\.\'"';
$data_bad = 'abcABC012~!###$%^&*()';
$re = '%^[a-zA-Z0-9+\- /\\\\.\'"]*$%';
echo($re ."\n");
if (preg_match($re, $data_good)) {
echo("CORRECT: Good data matches.\n");
} else {
echo("ERROR! Good data does NOT match.\n");
}
if (preg_match($re, $data_bad)) {
echo("ERROR! Bad data matches.\n");
} else {
echo("CORRECT: Bad data does NOT match.\n");
}
?>
The following regex will match a single character that fits the description you gave:
[a-zA-Z0-9\ \\\/\.\'\"]
If your point is to insure that ONLY characters in this range of characters are used in your string, then you can use the negation of this which would be:
[^a-zA-Z0-9\ \\\/\.\'\"]
In the second case, you could use your regex to find the bad stuff (that you don't want to be included), and if it didn't find anything then your string pattern must be kosher, because I'm assuming that if you find one character that is not in the proper range, then your string is not valid.
so to put it in PHP syntax:
$regex = "[^a-zA-Z0-9\ \\\/\.\'\"]"
if preg_match( $regex, ... ) {
// handle the bad stuff
}
Edit 1:
I've completely ignored the fact that backslashes are special in php double-quoted strings, so here is a correcting to the above code:
$regex = "[^a-zA-Z0-9\\ \\\\\\/\\.\\'\\\"]"
If that doesn't work it shouldn't take too much for someone to debug how many of the backslashes need to be escaped with a backslash, and what other characters need also to be escaped....

Categories