I'm trying to find a regex that will match a specific expression in the following format:
name = value
However, I need it to not match:
name.extra = value
I have the following regex:
([\w\#\-]+) *(\=|\>|\>\=|\<|\<\=) *([^\s\']+)
which matches the first expression, but also matches the second expression (extra = value).
I need a regex that will match only the first expression and not the second (i.e. with a dot).
Just add ^ beginning and $ ending to your expression
^([\w\#\-]+) *(\=|\>|\>\=|\<|\<\=) *([^\s\']+)$
Negative lookbehind assertion (?<!) might be what you are looking for.
For a simple assignment: (?<!\.)\b(\w+)\s*=\s*(\w+)
summary:
(?<!\.) = prevent the character . at that location
\b = beginning of a word
The captured words are:
\1 = destination name
\2 = source name
and using the regex you specified, this should give something near this:
(?<!\.)\b([\w\#\-]+) *(\=|\>|\>\=|\<|\<\=) *([^\s\']+)
You don't say what language you're using, but it sounds like you don't need to use regexes at all.
If you're using PHP, then use the explode function to break apart on the =. Then check to see if the argument name has a period in it.
Related
I am trying to validate following type of string using regular expressions in PHP. Using PHP 5.5.9.
String is in following format:
/[sometext]/course/[sometext1]/[sometext2]
What I need is a regex that will accept string that is only in that format and nothing else. Meaning these would be invalid:
/aaa/course/bbb/ccc/
/aaa/course/bbb/ccc/ddd
What I have so far is this:
/\/(?P<domain>.+?)\/course\/(?P<courseid>.+?)\/(?P<reportname>.+?)/
Any ideas?
Update:
With the help from all posters and especially wiktor-stribi%c5%bcew I got this one that works:
$regex = '#^/(?P<domain>[^/]+)/course/(?P<courseid>[^/]+)/(?P<reportname>[^/]+)$#';
You can use the following regular expression:
^\/(?P<domain>[^\/]+)\/course\/(?P<courseid>[^\/]+)\/(?P<reportname>[^\/]+)$
PHP:
$re = '~^/(?P<domain>[^/]+)/course/(?P<courseid>[^/]+)/(?P<reportname>[^/]+)$~';
See the regex demo
The [^\/] is a negated character class that matches any character but /.
The ^ and $ are usually enough to make sure your input starts and ends with the current pattern (you can replace them with \A and \z respectively to make sure the \z matches at the very end of the string, or use ^/$ with the /D modifier).
Even if you use lazy .+? dot matching, the . can overflow several / delimiters if it is necessary to return a valid match.
first... use something other than '/' as your delimiter (the slashes as the beginning and end of the regex)... it makes it easier to write the regex without having to escape the delimiter within
$regex = '#^/[a-z]+/[^/]+/[a-z]+/[a-z]+$#'
I want to write a regex with assertions to extract the number 55 from string unknownstring/55.1, here is my regex
$str = 'unknownstring/55.1';
preg_match('/(?<=\/)\d+(?=\.1)$/', $str, $match);
so, basically I am trying to say give me the number that comes after slash, and is followed by a dot and number 1, and after that there are no characters. But it does not match the regex. I just tried to remove the $ sign from the end and it matched. But that condition is essential, as I need that to be the end of the string, because the unknownstring part can contain similar text, e.g. unknow/545.1nstring/55.1. Perhaps I can use preg_match_all, and take the last match, but I want understand why the first regex does not work, where is my mistake.
Thanks
Use anchor $ inside lookahead:
(?<=\/)\d+(?=\.1$)
RegEx Demo
You cannot use $ outside the positive lookahead because your number is NOT at the end of input and there is a \.1 following it.
Here's the regex:
"'(\d{4})-(.*)-(\d{4})'i"
I want to match the first part of number (\d{4}) which must same as last part
Like this:
1111-abcdefg-2222 = invalid
1111-x-1111 = valid
0000-rwrgreheherhe-0000 = valid
1234-abcd-5678 - invalid
how can I achieve this?
UPDATE
I use the following script to check the output
$i = '1111-abcd-1111';
preg_match("'(\d{4})-(.*)-(\1)'i",$i,$m);
echo print_r($m,true);
but return empty array?
Use a backreference:
'/(\d{4})-(.*)-\1/i'
\1 equals to what you captured in the first capture group.
Use \1 as a backreference to your first capture group:
'~(\d{4})-(.*)-\1~'
See it here in action: http://codepad.viper-7.com/2Jw0dL
You need to use back-reference:
"'(\d{4})-(.*)-\1'i"
preg_match("'(\d{4})-(.*)-(\g1)'i",$i,$m);
add the \g1 to the back reference:
http://php.net/manual/en/regexp.reference.back-references.php
As of PHP 5.2.2, the \g escape sequence can be used for absolute and relative referencing of subpatterns. This escape sequence must be followed by an unsigned number or a negative number, optionally enclosed in braces. The sequences \1, \g1 and \g{1} are synonymous with one another. The use of this pattern with an unsigned number can help remove the ambiguity inherent when using digits following a backslash. The sequence helps to distinguish back references from octal characters and also makes it easier to have a back reference followed by a literal number, e.g. \g{2}1.
I do not know how to ignore an item from the ER.
just need to get P1, but this returns /P1.
is possible to just ignore the bar?
$pattern = "#(/P[0-9])?#";
There are two options here:
Exclude it from the group, P1 will be the contents in the capture group:
$pattern = "#/(P[0-9])#";
Use a lookbehind so that the / isn't even a part of the match, the entire match will be P1:
$pattern = "#(?<=/)P[0-9]#";
Note that I also removed the ? after your group because I don't think you actually want it, this makes the previous element optional so the regex (/P[0-9])? would match literal any string (it would match an empty string if /P[0-9] could not be matched).
With preg_* functions, you can use the \K trick that reset the begin of the match, example:
$pattern = '~/\KP[0-9]~';
<?php
$string = 'user34567';
if(preg_match('/user(^[0-9]{1,8}+$)/', $string)){
echo 1;
}
?>
I want to check if the string have the word user follows by number that can be 8 symbols max.
You're very close actually:
if(preg_match('/^user[0-9]{1,8}$/', $string)){
The anchor for "must match at start of string" should be all the way in front, followed by the "user" literal; then you specify the character set [0-9] and multiplier {1,8}. Finally, you end off with the "must match at end of string" anchor.
A few comments on your original expression:
The ^ matches the start of a string, so writing it anywhere else inside this expression but the beginning will not yield the expected results
The + is a multiplier; {1,8} is one too, but only one multiplier can be used after an expression
Unless you're intending to use the numbers that you found in the expression, you don't need parentheses.
Btw, instead of [0-9] you could also use \d. It's an automatic character group that shortens the regular expression, though this particular one doesn't save all too many characters ;-)
By using ^ and $, you are only matching when the pattern is the only thing on the line. Is that what you want? If so, use the following:
preg_match( '/^user[0-9]{1,8}[^0-9]$/' , $string );
If you want to find this pattern anywhere in a line, I would try:
preg_match( '/user[0-9]{1,8}[^0-9]/' , $string );
As always, you should use a reference tool like RegexPal to do your regular expression testing in isolation.
You were close, here is your regex : /^user[0-9]{1,8}$/
try the following regex instead:
/^user([0-9]{1,8})$/
Use this regex:
/^user\d{1,8}$/