preg_match_all regex issue for url routing - php

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.

Related

Twitter handle regular expression PHP [duplicate]

i'm not very firm with regular Expressions, so i have to ask you:
How to find out with PHP if a string contains a word starting with # ??
e.g. i have a string like "This is for #codeworxx" ???
I'm so sorry, but i have NO starting point for that :(
Hope you can help.
Thanks,
Sascha
okay thanks for the results - but i did a mistake - how to implement in eregi_replace ???
$text = eregi_replace('/\B#[^\B]+/','\\1', $text);
does not work??!?
why? do i not have to enter the same expression as pattern?
Match anything with has some whitespace in front of a # followed by something else than whitespace:
$ cat 1812901.php
<?php
echo preg_match("/\B#[^\B]+/", "This should #match it");
echo preg_match("/\B#[^\B]+/", "This should not# match");
echo preg_match("/\B#[^\B]+/", "This should match nothing and return 0");
echo "\n";
?>
$ php 1812901.php
100
break your string up like this:
$string = 'simple sentence with five words';
$words = explode(' ', $string );
Then you can loop trough the array and check if the first character of each word equals "#":
if ($stringInTheArray[0] == "#")
Assuming you define a word a sequence of letters with no white spaces between them, then this should be a good starting point for you:
$subject = "This is for #codeworxx";
$pattern = '/\s*#(.+?)\s/';
preg_match($pattern, $subject, $matches);
print_r($matches);
Explanation:
\s*#(.+?)\s - look for anything starting with #, group all the following letters, numbers, and anything which is not a whitespace (space, tab, newline), till the closest whitespace.
See the output of the $matches array for accessing the inner groups and the regex results.
#OP, no need regex. Just PHP string methods
$mystr='This is for #codeworxx';
$str = explode(" ",$mystr);
foreach($str as $k=>$word){
if(substr($word,0,1)=="#"){
print $word;
}
}
Just incase this is helpful to someone in the future
/((?<!\S)#\w+(?!\S))/
This will match any word containing alphanumeric characters, starting with "#." It will not match words with "#" anywhere but the start of the word.
Matching cases:
#username
foo #username bar
foo #username1 bar #username2
Failing cases:
foo#username
#username$
##username

Trouble With Regexp

I have to replace matches of patterns like <something:any-char> within a URL.
For example, a URL like this:
http://some-site.com/some-acion/pippo:1/mypar:asdasd/pippo2:sdd/ .....
should become:
http://some-site.com/some-acion/pippo:1/pippo2:sdd/ .....
In other words, I have to filter out any occurrence of mypar: from the URL.
I will use php for that.
I tried with RegExp:
.*[\/]+(sh:.*)[\/]?.*$
But it matches only strings like /pippo:3/mypar:wdfds. Strings like /pippo:2/mypar:asa/7pippo:1/ are not matched.
Any hint appreciated.
You could do this:
$url = "/pippo:2/mypar:asa/7pippo:1/";
$stripped = preg_replace("/\/mypar:.*?(\/|$)/", "$1", $url);
The combination of the lazy dot matching .*? with a positive lookahead (?=/|$) (either a / or the end of string) can be replaced with a mere any 0+ chars other than / with [^/]*:
'~/mypar:[^/]*~'
See the regex demo
The ~ delimiter makes it possible to use / in the pattern without escaping.
Pattern details:
/ - a forward slash
mypar: - a sequence of literal characters
[^/]* - zero or more characters other than / character
See PHP demo:
$re = '~/mypar:[^/]*~';
$str = "/pippo:2/mypar:asa/7pippo:1/";
$result = preg_replace($re, '', $str, 1);
echo $result;

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
}

Removing all characters and numbers except last variable with dash symbol

Hi I want to remove a characters using preg_replace in php so i have this code here which i want to remove the whole characters, letters and numbers except the last digit(s) which has dash(-) symbol followed by a digits so here's my code.
echo preg_replace('/(.+)(?=-[0-9])|(.+)/','','asdf1245-10');
I expect the result will be
-10
the problem is above is not working very well. I checked the pattern using http://www.regextester.com/ it seems like it works, but on the other side http://www.phpliveregex.com/ doesn't work at all. I don't know why but anyone who can help to to figure it out?
Thanks a lot
Here is a way to go:
echo preg_replace('/^.+?(-[0-9]+)?$/','$1','asdf1245-10');
Output:
-10
and
echo preg_replace('/^.+?(-[0-9]+)?$/','$1','asdf124510');
Output:
<nothing>
My first thinking is to use explode in this case.. make it simple like the following code.
$string = 'asdf1245-10';
$array = explode('-', $string);
end($array);
$key = key($array);
$result = '-' . $array[$key];
$result => '-10';
An other way:
$result = preg_match('~\A.*\K-\d+\z~', $str, $m) ? $m[0] : '';
pattern details:
\A # start of the string anchor
.* # zero or more characters
\K # discard all on the left from match result
-\d+ # the dash and the digits
\z # end of the string anchor
echo preg_replace('/(\w+)(-\w+)/','$2', 'asdf1245-10');

regex function[filename] pattern and function[string_with_escaped_characters] pattern

I'm trying to script and parse a file,
Please help with regex in php to find and replace the following patterns:
From: "This is a foo[/www/bar.txt] within a foo[/etc/bar.txt]"
To: "This is a bar_txt_content within a bar2_txt_content"
Something along those lines:
$subject = "This is a foo[/www/bar.txt] within a foo[/etc/bar.txt]";
$pattern = '/regex-needed/';
preg_match($pattern, $subject, $matches);
foreach($matches as $match) {
$subject = str_replace('foo['.$match[0].']', file_get_contents($match[0]), $subject);
}
And my second request is to have:
From: 'This is a foo2[bar bar ] bar bar].'
To: "this is a returned"
Something along those lines:
$subject = 'This is a foo2[bar bar \] bar bar].';
$pattern = '/regex-needed/';
preg_match($pattern, $subject, $matches);
foreach($matches as $match) {
$subject = str_replace('foo2['.$match[0].']', my_function($match[0]), $subject);
}
Please help in constructing these patterns...
If you always have a structure like foo[ ... ]
Then is very easy:
foo\[([^]]+)\]
That is .NET syntax but i'm sure the expressions is simple enough for you to convert.
Description of the regex:
Match the characters “foo” literally «foo»
Match the character “[” literally «[»
Match the regular expression below and capture its match into backreference number 1 «([^]]+)»
Match any character that is NOT a “]” «[^]]+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the character “]” literally «]»
Luc,
this should help you get started.
http://php.net/manual/en/function.preg-replace.php
You may have to setup a loop and increase the counter, using preg_replace with a limit of 1 to replace only the first instance.
In order to match foo[/www/bar.txt]:
the regex should be something like:
foo\[\/www\/([A-Za-z0-9]*)\.txt\]
The backslashes are there to cancel the special meaning of some characters in your regexp.
It will match foo[/www/.[some file name].txt, and ${1} will contain the filename without the .txt as brackets form groups which can be used in the replaced expression. ${1} will contain what was matched in the first round brackets, ${2} will contain what was matched in the second one, etc ...
Therefore your replaced expression should be something like "${1}_txt_content". Or in the second iteration "${1}2_txt_content".
[A-Za-z0-9]* means any alphanumeric character 0 or more times, you may want to replace the * with a + if you want at least 1 character.
So try:
$pattern = foo\[\/www\/([A-Za-z0-9]*)\.txt\];
$replace = "${1}_txt_content";
$total_count = 1;
do {
echo preg_replace($pattern, $replace, $subject, 1, $count);
$replace = "${1}" + ++$total_count + "_txt_content";
} while ($count != 0);
(warning, this is my first ever PHP program, so it may have mistakes as I cannot test it ! but I hope you get the idea)
Hope that helps !
Tony
PS: I am not a PHP programmer but I know this works in C#, for example, and looking at the PHP documentation it seems that it should work.
PS2: I always keep this website bookmarked for reference when I need it: http://www.regular-expressions.info/
$pattern = '/\[([^\]]+)\]/';
preg_match_all($pattern, $subject, $matches);
print_r($matches['1']);
found the correct regex I needed for escaping:
'/foo\[[^\[]*[^\\\]\]/'

Categories