Regex Lookahead (PHP) - php

I have a quick question about regex for PHP.
My code:
^(\d{0,4}?)\.(?=(\d{1,2}))$
doesn't seem to work, where it's supposed to capture an optional group of up to 4 digits, then look ahead and conditionally capture a period based on if it captures a group of 1-2 digits.
Does anyone know why this doesn't work?

That's not the right way to do it - nothing about your regex indicates that the . is optional.
Try:
^(\d{0,4})(?:\.(\d{1,2}))?$
This will match up to four digits, which may optionally be followed by a dot, then one or two digits. In any case, the two subpatterns will contain the groups of digits.

Related

How to Retrieve Overlapping Matches with Complex Regex and Preg_Match_All in PHP

Have read the following which have some overlap (pun intended!) with the issue I am facing:
preg_match_all how to get *all* combinations? Even overlapping ones
Overlapping matches with preg_match_all and pattern ending with repeated character
However, I don’t really know how to apply their answers to my issue which is a little more complicated.
My regex that I use with preg_match_all():
/.{240}[^\[]Order[^ ][^\(].{9}/u
With the following string:
56A.  Subject to the provisions of this Act, any decision of the Court or the Appeal Board shall be final and conclusive, and no decision or order of the Court or the Appeal Board shall be challenged, appealed against, reviewed, quashed or called into question in any court and shall not be subject to any Quashing Order, Prohibiting Order, Mandatory Order or injunction in any court on any account.[20/99; 42/2005]
I intended it to match exactly 3 times. The first match has “Quashing Order” 9 characters before the end. The second match has “Prohibiting Order” 9 characters before the end. The third match has “Mandatory Order” 9 characters before the end.
However, as expected it’s only matching the first one, as the expected matches are overlapping.
I applied what I read in the other posts, I tried this:
(?=(.{240}[^\[]Order[^ ][^\(].{9}))
I still don’t get what I need.
How do I solve this?
You can use
\w+\s+Order\b
See the regex demo.
Regex details
\w+ - one or more word chars
\s+ - 1 or more whitespaces
Order\b - a whole word Order, as \b is a word boundary.
You will need to use a positive look-behind assertion for .{240}, just like the answer you found suggests using a positive look-ahead assertion for .{9}:
/(?<=.{240})[^\[]Order[^ ][^\(](?=.{9})/u
This RE matches your string only twice because of [^ ], as #bobblebubble said. Adjust that part as necessary.

Specific Regex for nubmers with commas and hyphens

I have a filename i need to validate using preg_match in PHP, but i dont know much about regex patterns to fix my issue.
The string i am trying to validate is
2 numbers (0-9), a comma, 2 numbers (0-9), a hyphen, 2 numbers (0-9), a comma, 2 numbers (0-9)
An example is 47,60-51,00
I have tried the following
(-)?[0-9]+((,|-)[0-9]+)*
and
^[0-9][0-9,-]-[0-9,-][0-9]$
But both seem to fail one way or another. Could someone help point me in the right direction
You want to match the comma as a separate match but adding it to a character class [0-9,-] it can also match a digit or -
To match that format in a more specific way, you could use this pattern with a quantifier {2} to repeat matching a digit and match the comma's and hyphen at the expected position.
^[0-9]{2},[0-9]{2}-[0-9]{2},[0-9]{2}$
Regex demo
If you want the match to start with an optional hyphen you could start the pattern with ^-?

PCRE(php) Is it possible to check if sequence of numbers contains only unique number for that sequence?

Assuming I have a set of numbers (from 1 to 22) divided by some trivial delimiters (comma, point, space, etc). I need to make sure that this set of numbers does not contain any repetition of the same number. Examples:
1,14,22,3 // good
1,12,12,3 // not good
Is it possible to do via regular expression?
I know it's easy to do using just php, but I really wander how to make it work with regex.
Yes, you could achieve this through regex via negative looahead.
^(?!.*\b(\d+)\b.*\b\1\b)\d+(?:,\d+)+$
(?!.*\b(\d+)\b.*\b\1\b) Negative lookahead at the start asserts that the there wouldn't be a repeated number present in the match. \b(\d+)\b.*\b\1\b matches the repeated number.
\d+ matches one or more digits.
(?:,\d+)+ One or more occurances of , , one or more digits.
$ Asserts that we are at the end .
DEMO
OR
Regex for the numbers separated by space, dot, comma as delimiters.
^(?!.*\b(\d+)\b.*\b\1\b)\d+(?:([.\s,])\d+)(?:\2\d+)*$
(?:([.\s,])\d+) capturing group inside this non-capturing group helps us to check for following delimiters are of the same type. ie, the above regex won't match the strings like 2,3 5.6
DEMO
You can use this regex:
^(?!.*?(\b\d+)\W+\1\b)\d+(\W+\d+)*$
Negative lookahead (?!.*?(\b\d+)\W+\1\b) avoids the match when 2 similar numbers appear one after another separated by 1 or more non-word characters.
RegEx Demo
Here is the solution that fit my current need:
^(?>(?!\2\b|\3\b)(1\d{1}|2[0-2]{1}|\d{1}+)[,.; ]+)(?>(?!\1\b|\3\b)(1\d{1}|2[0-2]{1}|\d{1}+)[,.; ]+)(?>(?!\1\b|\2\b)(1\d{1}|2[0-2]{1}|\d{1}+))$
It returns all the sequences with unique numbers divided by one or more separator and also limit the number itself from 1 to 22, allowing only 3 numbers in the sequence.
See working example
Yet, it's not perfect, but work fine! Thanks a lot to everyone who gave me a hand on this!

Regex matching multiple pattern

I have these
name
name[one]
name[one][two]
name[one][two][three]
I want to be able to match them like this:
[name]
[name, one]
[name, one, two]
[name, one, two, three]
Here's my regex I've tried:
/([\w]+)(?:(?:\[([\w]+)\])+)?/
I just can't quite to seem to get it right, only gets the last square brackets
You can't have a dynamic number of captures; the number of captures is exactly equal to the number of capture parenthesis pairs ((?:...) don't count). You have two capture parenthesis pairs, that means you get two captures - no more, no less.
To handle variable number of matches, use submatches (in a replace with a function, if your language supports that), or split.
You haven't labeled with a programming language, so this is as specific as I can go.
This should do ([\w]+)(?:\[([\w]+)\]\+)?
http://regex101.com/r/mF8pC8/3
Changes from original regex - removed extra capture and added \ before last +.
1st Capturing group ([\w]+)
[\w]+ match a single character present in the list below
Quantifier: Between one and unlimited times, as many times as possible, giving back as needed [greedy]
\w match any word character [a-zA-Z0-9_]
(?:\[([\w]+)\]\+)? Non-capturing group
Quantifier: Between zero and one time, as many times as possible, giving back as needed [greedy]
\[ matches the character [ literally
2nd Capturing group ([\w]+)
[\w]+ match a single character present in the list below
Quantifier: Between one and unlimited times, as many times as possible, giving back as needed [greedy]
\w match any word character [a-zA-Z0-9_]
\] matches the character ] literally
\+ matches the character + literally
g modifier: global. All matches (don't return on first match)
You can't repeat groups in a regex. You can write them out a number of times though. This works for up to three groups in square brackets. You can add more if you like.
(\w+)\[(\w+)\](?:\[(\w+)\])?(?:\[(\w+)\])?
You can not have dynamic number of captures with php regexp...
Why not just, write something like: explode('[',strtr('name[one][two][three]', [']'=>''])) - it will give you desired result.

Regex to allow numbers and only one hyphen in the middle

I am trying to write a regular expression to allow numbers and only one hypen in the middle (cannot be at start or at the end)
say pattern: 02-04 , 02are acceptable but
pattern: -- or - or -02 or 04- or 02-04-06 are unacceptable
I tried something like this but this would allow - at the beginning and also allow multiple -
'/^[0-9 \-]+$/'
I am not that good with regex so a little explanation would be real helpful.
EDIT: Sorry to bug you again with this but I need the numbers to be of only 2 digits (123-346) should be considered invalid.
Try this one:
/^\d{1,2}(-\d{1,2})?$/
One or two digits, followed by, optionally, ( a hyphen followed by one or two digits)
Fairly easy:
^\d+(-\d+)?$
At least one (+) digit (\d), followed by an optional group containing a hyphen-minus (-), followed by at least one digit again.
For strings containing only that pattern the following should work
^(\d{2}-)?\d{2}$
A group of 2 digits followed by minus ending with a group of 2 digits without minus.

Categories