Explanation requested for a specific regxp - php

I have an issue understanding the "+" sign.
Here is my example:
$array = array("123 Main St.");
$match = preg_grep("%^\d{1,5}\s[A-Za-z.]+\s[A-Za-z.]{2,7}$%",$array);
foreach($match as $value) {
echo "<pre>" .$value . "<br>";
}
So basically this totally works, but I don't understand the "+" sign's job. If I remove it, it does not work.

+ in regex is to match 1 or more of preceding group OR pattern.
In your example: [A-Za-z.]+ will match 1 OR more of English alphabets (case insensitive) OR a literal dot.
Read more about regular expressions

+ is equal to {1,} meaning 1 or more

+ means at least one or more occurrences of the expression.
In your case [A-Za-z.]+ means there shall be at least a single alphabet or a dot.

Related

PHP preg_match to allow only numbers,spaces '+' and '-'

I need to check to see if a variable contains anything OTHER than 0-9 and the "-" and the "+" character and the " "(space).
The preg_match I have written does not work. Any help would be appreciated.
<?php
$var="+91 9766554433";
if(preg_match('/[0-9 +\-]/i', $var))
echo $var;
?>
You have to add a * as a quantifier to the whole character class and add anchors to the start and end of the regex: ^ and $ means to match only lines containing nothing but the inner regex from from start to end of line. Also, the i modifier is unnecessary since there is no need for case-insensitivity in this regex.
This should do the work.
if(!preg_match('/^[0-9 +-]*$/', $var)){
//variable contains char not allowed
}else{
//variable only contains allowed chars
}
Just negate the character class:
if ( preg_match('/[^0-9 +-]/', $var) )
echo $var;
or add anchors and quantifier:
if ( preg_match('/^[0-9 +-]+$/', $var) )
echo $var;
The case insensitive modifier is not mandatory in your case.
You can try regex101.com to test your regex to match your criteria and then on the left panel, you'll find code generator, which will generate code for PHP, Python, and Javascript.
$re = "/^[\\d\\s\\+\\-]+$/i";
$str = "+91 9766554433";
preg_match($re, $str, $matches);
You can take a look here.
Try see if this works. I haven't gotten around to test it beforehand, so I apologize if it doesn't work.
if(!preg_match('/^[0-9]+.-.+." ".*$/', $var)){
//variable contains char not allowed
}else{
//variable only contains allowed chars
}

preg_match_all regex issue for url routing

for an url routing I have
Patern :
/^\/stuff\/other-stuff\/(?:([^\/]\+?))$/i
Subject :
/stuff/other-stuff/foo-AB123456.html
why $num_matches is equal to 0 ??
$num_matches = preg_match_all($patern, $subject, $matches);
Help should be greatly appreciated :)
because of this:
[^\/]\+?
firstly there is no slash after other-stuff so you cannot find the sentence with a negated / secondly the + must not be escaped if you are doing this kind of match . + must only be escaped when you are doing a literal match.
the corrected regex should be :
^\/stuff\/other-stuff\/(?:(.+?))$
demo here : http://regex101.com/r/aV9cR0
will match foo-AB123456.html in the first capture
$patern= "#^/stuff/other-stuff/([^/]+)$#i";
$subject = "/stuff/other-stuff/foo-AB123456.html";
preg_match_all($patern, $subject, $matches);
print_r($matches[1]);
It looks to me like your regex could be simplified to something like:
(?i)^/stuff/other-stuff/[\w-.]+$
It would work like this:
<?php
$regex="~(?i)^/stuff/other-stuff/([\w-./]+)$~";
$string = "/stuff/other-stuff/foo-AB123456.html";
$hit = preg_match($regex,$string,$m);
echo $m[0]."<br />";
echo $m[1]."<br />";
?>
Output:
/stuff/other-stuff/foo-AB123456.html
foo-AB123456.html
Note that this could be done in a number of different ways.
Here are some details about the regex.
The ~ delimiter is nicer than the original / because you don't have to escape the slashes.
The parentheses in ([\w-.]+) capture the end of the url into Group 1. This is why $m[1] yields foo-AB123456.html
After the final slash, [\w-./]+ matches any number of letters or digits, underscores, dashes, dots and forward slashes. This is a "mini-spec" for what characters we expect there. If you want to allow anything at all, you could go with a simple dot.

php expressions preg_match

I have been trying to figure this out really hard and I cannot came out with a solution ,
I have an arrary of strings which is
"Descripcion 1","Description 2"
and I need to filter by numbers, so I thought maybe I can use preg_match() and find when there is exactly 1 number 1 or two or etc, and do my logic, becouse the string before the number may change, but the number cannot, I have tried using
preg_match(" 1{1}","Description 1")
which is suppossed to return true when finds an space followed by the string "1" exactly one time but returns false.
Maybe some of you have had more experience with regular expressions in php and can help me.
Thank you very much in advance.
You could use strpos instead of preg_match!
foreach($array as $string) {
if(strpos($string, ' 1') !== false) {
//String contains " 1"!!
}
}
This would be much faster then a regular expression.
Or, if the Number has to be at the end of the string:
foreach($array as $string) {
if(substr($string, -2) == ' 1') {
//String ends with " 1"!!
}
}
You forgot the regex delimiters. Use preg_match('/ 1/', ...) instead.
However, you do not need a regex at all if you just want to test if a string is contained within another string! See Lars Ebert's answer.
You might have success using
if (preg_match('/(.*\s[1])/', $var, $array)) {
$descrip = $array[1];
} else {
$descrip = "";
}
I tested the above regex on the 3 separate string values of descripcion 1, thisIsAnother 1, andOneMore 1. Each were found to be true by the expression and were saved into group 1.
The explanation of the regex code is:
() Match the regular expression between the parentheses and capture the match into backreference number 1.
.* Match any single character that is not a line break character between zero and as many times possible (greedy)
\s Match a single whitespace character (space, tab, line break)
[1] Match the character 1

Attempting to understand handling regular expressions with php

I am trying to make sense of handling regular expression with php. So far my code is:
PHP code:
$string = "This is a 1 2 3 test.";
$pattern = '/^[a-zA-Z0-9\. ]$/';
$match = preg_match($pattern, $string);
echo "string: " . $string . " regex response: " , $match;
Why is $match always returning 0 when I think it should be returning a 1?
[a-zA-Z0-9\. ] means one character which is alphanumeric or "." or " ". You will want to repeat this pattern:
$pattern = '/^[a-zA-Z0-9. ]+$/';
^
"one or more"
Note: you don't need to escape . inside a character group.
Here's what you're pattern is saying:
'/: Start the expressions
^: Beginning of the string
[a-zA-Z0-9\. ]: Any one alphanumeric character, period or space (you should actually be using \s for spaces if your intention is to match any whitespace character).
$: End of the string
/': End the expression
So, an example of a string that would yield a match result is:
$string = 'a'
Of other note, if you're actually trying to get the matches from the result, you'll want to use the third parameter of preg_match:
$numResults = preg_match($pattern, $string, $matches);
You need a quantifier on the end of your character class, such as +, which means match 1 or more times.
Ideone.

php preg_replace , I need to replace everything after a dot (e.g 340.38888 > need to get clean 340)

I need to replace everything after a dot . I know that it can be done with regex but I'm still novice and I don't understand the proper syntax so please help me with this .
I tried the bellow code but doesn't work :
$x = "340.888888";
$pattern = "/*./"
$y = preg_replace($pattern, "", $x);
print_r($x);
thanks ,
Michael
I may be wrong, but this sounds like using the RegEx hammer for an eminently non-nail shaped problem. If you're just trying to truncate a positive floating point number, you can use
$x = 340.888888;
$y = floor($x);
Edit: As pointed out by Techpriester's comment, this will always round down (so -3.5 becomes -4). If that's not what you want, you can just use a cast, as in $y = (int)$x.
As already mentioned by others: there are better ways to get the integer part of a number.
However, if you're asking this because you want to learn some regex, here's how to do it:
$x = "340.888888";
$y = preg_replace("/\..*$/", "", $x);
print_r($y);
The regex \..*$ means:
\. # match the literal '.'
.* # match any character except line breaks and repeat it zero or more times
$ # match the end of the string
You could also do...
$x = "340.888888";
$y = current(explode(".", $x));
The . in regex means "any characters (except new line). To actually match a dot, you need to escape it as \..
The * is not valid by itself. It must appear as x*, which means the pattern "x" repeated zero or more times. In your case, you need to match a digit, where \d is used.
Also, you wouldn't want to replace Foo... 123.456 as Foo 123. The digit should appear ≥1 times. A + should be used instead of a *.
So your replacement should be
$y = preg_replace('/\\.\\d+/', "", $x);
(And to ensure the number to truncate is of the form 123.456, not .456, use a lookbehind.
$y = preg_replace('/(?<=\\d)\\.\\d+/', "", $x);

Categories