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

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:]]*.

Related

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

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!

Sha 1 php, possible variations and regex

First,
Is it possible for a sha1 hash to be all numbers or letters,
And second is there any need for the start and end delimiters when using a regex to check for a sha 1 hash, ie,
/^[0-9a-f]{40}$/i
inplace of
/[0-9a-f]{40}/i
Is there any need to use the delimeters?
I ask as should I check if the pattern has at least one number and at least one letter, or does this not matter?
A sha1 hash is a 160 bit value that can be between all 0s and all 1s. This means that yes, in theory it can be all numbers or all letters (more specifically, the hex representation of it can be).
As for the beginning and ending markers, they are required unless you check the string in other ways. The two patterns you posted are not equivalent:
/^[0-9a-f]{40}$/i
A string that consists of and only of 40 character in 0-9 or a-f.
/[0-9a-f]{40}/i
A string that contains 40 character in 0-9 or a-f in a row.
In other words, the first pattern would consider this invalid whereas the second would not:
|0000000000000000000000000000000000000000|
The second pattern would match the 40 valid characters in the middle and not care about the rest of it.
You could effectively turn the second pattern into the first if you also used strlen to verify that the string is exactly 40 characters. This would be a bit redundant though, as you'd essentially then have a pattern of:
A string that: (contains 40 characters in 0-9 or a-f in a row) and (is exactly 40 characters).
The first version expresses it more compactly, though the second is a bit more obvious.

Regex help to match more than one letter

I am using the following regex to match an account number. When we originally put this regex together, the rule was that an account number would only ever begin with a single letter. That has since changed and I have an account number that has 3 letters at the beginning of the string.
I'd like to have a regex that will match a minimum of 1 letter and a maximum of 3 letters at the beginning of the string. The last issue is the length of the string. It can be as long as 9 characters and a minimum of 3.
Here is what I am currently using.
'/^([A-Za-z]{1})([0-9]{7})$/'
Is there a way to match all of this?
You want:
^[A-Za-z]([A-Za-z]{2}|[A-Za-z][0-9]|[0-9]{2})[0-9]{0,6}$
The initial [A-Za-z] ensures that it starts with a letter, the second bit ([A-Za-z]{2}|[A-Za-z][0-9]|[0-9]{2}) ensures that it's at least three characters long and consists of between one and three letters at the start, and the final bit [0-9]{0,6} allows you to go up to 9 characters in total.
Further explaining:
^ Start of string/line anchor.
[A-Za-z] First character must be alpha.
( [A-Za-z]{2} Second/third character are either alpha/alpha,
|[A-Za-z][0-9] alpha/digit,
|[0-9]{2} or digit/digit
) (also guarantees minimum length of three).
[0-9]{0,6} Then up to six digits (to give length of 3 thru 9).
$ End of string/line marker.
Try this:
'/^([A-Za-z]{1,3})([0-9]{0,6})$/'
That will give you from 1 to 3 letters and from 3 to 9 total characters.

Categories