Specific Regex for nubmers with commas and hyphens - php

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 ^-?

Related

Regular Expressions to Match Decimal 12,2 With Comma to Separate Groups of Thousands

I want to make sure that the input is no more than 10 digits before the decimals point so it will match DECIMAL(12,2).
I already tried :
^(?=.{0,13}$)[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?$
But it counts the digits after decimals too, so what I want to match is:
1,111,111,111.00
so it will keep matching with or without the decimals, what I tried only can match with:
1,111,111,111
You can assert from the start of the string what is on the right is 1-10 times a digit followed by an optional comma followed by a dot and 2 digits.
Then use the pattern to match the exact format.
Note that in your pattern the (\.[0-9]+)? at the end can match more than 2 digits. If you want to match an optional dot and 2 digits, use (?:\.[0-9]{2})?
^(?=(?:\d,?){1,10}(?:\.\d{2})?$)[0-9]{1,3}(?:,[0-9]{3})*(?:\.[0-9]+)?$
Regex demo

PHP Regex match 4 digits and 2 letters in random order

I'm trying to create regex, which will match 4 digits and 2 letters in any order. Letters can be in lower and upper cases.
Example:
a1234B
17AF45
aR1307
Any advice would be appreciated.
Thanks.
A brute force approach to this might be to just use two positive lookaheads:
^(?=.*[A-Za-z].*[A-Za-z])(?=.*\d.*\d.*\d.*\d).{6}$
This would match exactly two letters, lowercase or uppercase, and four digits, for a total of six characters.
Demo
For a deeper explanation, consider the first lookahead:
^(?=.*[A-Za-z].*[A-Za-z])
This says to assert (but not match) from the start of the string that two letters occur anywhere in the string. Assuming this is true, then the regex engine will evaluate the next lookahead, which checks for four numbers. If that also be true, then all that is needed is to match any 6 characters. Those matching characters must only letters and numbers, due to the lookaheads.

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 Lookahead (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.

Regex to change to must include at least a number and letter?

My regex at the minute is like this
'/[a-z0-9]{40}/i'
Which will match any string with no spaces that contains letters and/or numbers.
How can I change it so that it must at least include at least one number and at least one alphabet character so that if the string was all numbers or all letters it would not be matched?
Thanks
/([:alpha:].*[:digit:]|[:digit:].*[:alpha:])/
This requires a number to follow a letter, or a letter to follow a number.
From your original regex, it appears that you want to enforce a requirement for 40 characters total. For that, try:
/^(.*[:alpha:].*[:digit:].*|.*[:digit:].*[:alpha:].*){40}$/
Note the extra .*'s. As long as there's one alpha and one digit, the other characters can be anything. As long as there are 40 of them.
If you want to avoid matching whitespace, replace each .* with [^[:space:]]*.

Categories