Matching exactly 8 digits with 0 or more dashes - regex

I am trying to match an exactly 8 digit phone number that has 0 or more dashes in it. For example, the following should all match:
12345678
123456-78
1234-5678
1-2-3-4-5-6-7-8
If I ignore the dashes, it is rather simple. I can just use:
[\d]{8}
If I want to match a string containing at least 8 characters (digits and dashes) I can use:
[\d-]{8,}
However, here I can't put an upper bound on the number of characters because I don't know how many dashes the number would have.
The only way I thought of would be to use:
[0-9][-]?[0-9][-]?[0-9][-]?[0-9][-]?[0-9][-]?[0-9][-]?[0-9][-]?[0-9]
However, this seems really messy for something that (at least in my mind) seems simple. Is there an easier way to do this?

You can use this regex with optional - after each digit:
^([0-9]-?){8}$
If your regex supports \d then use:
^(\d-?){8}$
RegEx Demo

You should use
^[0-9](-?[0-9]){7}$
^([0-9]-?){8}\b$
See the regex demo #1 and regex demo #2, where \b is used to make sure the last char is a digit (that is a word char).
Details
^ - start of string
[0-9] to match a digit since \d in various regex flavors may match more than just ASCII digits from 0 to 9.
(-?[0-9]){7} - matches 7 sequences of an optional hyphen and a digit, and will not allow trailing hyphen at the end of the string.
([0-9]-?){8} - matches eight occurrences of a digit followed with an optional - char
\b$ - is a trick to make sure the last char is of a word type. Since the pattern can only match a - (a non-word char) or a digit at the end, \b automatically makes sure the last char is a digit.

Related

Need a regex for ONLY Alphanumeric (no pure numbers or letters) AND limit to exactly 10 characters?

I've run into some issues with this one and cannot find it in past questions.
Criteria:
Reject pure digits
Reject pure letters
Reject any symbols
Accept ONLY Alphanumeric combo
MUST be equal to 10 characters total
Here is what I have made and the problems with each:
^(?!^\d*$)[a-zA-Z\d]{10}$
This fails criteria #2
^[a-zA-Z0-9]{10}$
This fails criteria #1
I have tried some others that meet all criteria but fail the 10 char limit.
Any help is appreciated.
You may use a second lookahead:
^(?!\d+$)(?![a-zA-Z]+$)[a-zA-Z\d]{10}$
See the regex demo and the Regulex graph:
Details
^ - start of string
(?!\d+$) - a negative lookahead that makes sure the whole string is not composed of just digits
(?![a-zA-Z]+$) - the whole string cannot be all letters
[a-zA-Z\d]{10} - 10 letters or digits
$ - end of string.
Try this:
(?=^.{10}$)^([a-z]+\d[a-z0-9]*|\d+[a-z][a-z0-9]*)$
Demo
Explanation:
(?=^.{10}$)^([a-z]+\d[a-z0-9]*|\d+[a-z][a-z0-9]*)$
(?=^.{10}$) # there's exactly 10 characters following
^( | )$ # we match the entire string, containing either:
[a-z]+\d[a-z0-9]* # letters, followed by a number, followed by alphanumerics, or
\d+[a-z][a-z0-9]* # numbers, followed by a letter, followed by alphanumerics
Use lookahead to find at least one char of each type you require, and specify the length and char limitation in the "regular" part of your regex:
^(?=.*[a-zA-Z])(?=.*\d)[0-9a-zA-Z]{10}$
(?=.*[a-zA-Z])- Look ahead and find a letter,
(?=.*\d) - Look ahead and find a digit
[0-9a-zA-Z]{10} - exactly 10 digit/letter chars

Regex - Exactly 7 digits no more no less

I am looking for help here. I want to write a regex to help me find EXACTLY a 7 digit in string - no more or less.
For instance in this string:
1234567 RE:TKT-2744870-R6P1G0: Gentle Reminder
It should return only 1234567
In this one:
12345678 RE:TKT-2744870-R6P1G0: Gentle Reminder
It should return none.
Can you help me with this one.
thanks in advance.
The proper regex should include \d{7} (7 digits) and 2 "border criteria",
for both start and end of the match, to block matching of a fragment
from longer sequence of digits.
My first thought was that neither before nor after the match there can be any digit.
But as I see from your example, these border criteria should be extended.
The set of "forbidden" chars (either before or after the match) should
include also - and letters.
E.g. 2744870 in your example data contains just 7 digits (no more, no less),
but you still don't want it to be matched, apparently because they are surrounded with - chars.
To keep the regex short, I propose:
(?<![\w-])\d{7}(?![\w-])
Details:
(?<![\w-]) - Negative lookbehind for word char or -.
\d{7} - 7 digits.
(?![\w-]) - Negative lookahead for word char or -.
If you decide to extend the set of "forbidden" chars in both border criteria,
just add them to [...] fragments in lookbehind / lookahead (but - char
should remain at the end, otherwise it must be quoted with \).
Regex like (\d{7})[^\d] (in other proposition) is wrong,
as it matches last 7 digits from any longer sequence of digits
(no "front border criterion").
It matches also both 2744870 (surronded with - chars), which are not
to be matched.
This one should do for your examples:
(\d{7})[^\d]
The first matching group contains the seven digits.
Alternatively –as suggested in the comments– you can use a negative lookahead to only match the seven digits and not require matching groups:
^\d{7}(?!\d)

regex: find one-digit number

I need to find the text of all the one-digit number.
My code:
$string = 'text 4 78 text 558 my.name#gmail.com 5 text 78998 text';
$pattern = '/ [\d]{1} /';
(result: 4 and 5)
Everything works perfectly, just wanted to ask it is correct to use spaces?
Maybe there is some other way to distinguish one-digit number.
Thanks
First of all, [\d]{1} is equivalent to \d.
As for your question, it would be better to use a zero width assertion like a lookbehind/lookahead or word boundary (\b). Otherwise you will not match consecutive single digits because the leading space of the second digit will be matched as the trailing space of the first digit (and overlapping matches won't be found).
Here is how I would write this:
(?<!\S)\d(?!\S)
This means "match a digit only if there is not a non-whitespace character before it, and there is not a non-whitespace character after it".
I used the double negative like (?!\S) instead of (?=\s) so that you will also match single digits that are at the beginning or end of the string.
I prefer this over \b\d\b for your example because it looks like you really only want to match when the digit is surrounded by spaces, and \b\d\b would match the 4 and the 5 in a string like 192.168.4.5
To allow punctuation at the end, you could use the following:
(?<!\S)\d(?![^\s.,?!])
Add any additional punctuation characters that you want to allow after the digit to the character class (inside of the square brackets, but make sure it is after the ^).
Use word boundaries. Note that the range quantifier {1} (a single \d will only match one digit) and the character class [] is redundant because it only consists of one character.
\b\d\b
Search around word boundaries:
\b\d\b
As explained by the others, this will extract single digits meaning that some special characters might not be respected like "." in an ip address. To address that, see F.J and Mike Brant's answer(s).
It really depends on where the numbers can appear and whether you care if they are adjacent to other characters (like . at the end of a sentence). At the very least, I would use word boundaries so that you can get numbers at the beginning and end of the input string:
$pattern = '/\b\d\b/';
But you might consider punctuation at the end like:
$pattern = '/\b\d(\b|\.|\?|\!)/';
If one-digit numbers can be preceded or followed by characters other than digits (e.g., "a1 cat" or "Call agent 7, pronto!") use
(?<!\d)\d(?!\d)
Demo
The regular expression reads, match a digit (\d) that is neither preceded nor followed by digit, (?<!\d) being a negative lookbehind and (?!\d) being a negative lookahead.

How can I recognize a valid barcode using regex?

I have a barcode of the format 123456########. That is, the first 6 digits are always the same followed by 8 digits.
How would I check that a variable matches that format?
You haven't specified a language, but regexp. syntax is relatively uniform across implementations, so something like the following should work: 123456\d{8}
\d Indicates numeric characters and is typically equivalent to the set [0-9].
{8} indicates repetition of the preceding character set precisely eight times.
Depending on how the input is coming in, you may want to anchor the regexp. thusly:
^123456\d{8}$
Where ^ matches the beginning of the line or string and $ matches the end. Alternatively, you may wish to use word boundaries, to ensure that your bar-code strings are properly separated:
\b123456\d{8}\b
Where \b matches the empty string but only at the edges of a word (normally defined as a sequence consisting exclusively of alphanumeric characters plus the underscore, but this can be locale-dependent).
123456\d{8}
123456 # Literals
\d # Match a digit
{8} # 8 times
You can change the {8} to any number of digits depending on how many are after your static ones.
Regexr will let you try out the regex.
123456\d{8}
should do it. This breaks down to:
123456 - the fixed bit, obviously substitute this for what you're fixed bit is, remember to escape and regex special characters in here, although with just numbers you should be fine
\d - a digit
{8} - the number of times the previous element must be repeated, 8 in this case.
the {8} can take 2 digits if you have a minimum or maximum number in the range so you could do {6,8} if the previous element had to be repeated between 6 and 8 times.
The way you describe it, it's just
^123456[0-9]{8}$
...where you'd replace 123456 with your 6 known digits. I'm using [0-9] instead of \d because I don't know what flavor of regex you're using, and \d allows non-Arabic numerals in some flavors (if that concerns you).

Regular Expression - Start with 3538 and then contain 8 digits

E.g. match 353812345678 So far I have ^3538{1}[\d]{8} which works but does not restrict the length. How do I make sure the length is only a maximum of 12 digits?
If you want the number to be the only thing in the string: ^3538\d{8}$
If you just want the number in a string: \b3538\d{8}\b
^ is the start-of-string anchor, while $ is the end-of-string anchor, so the first one restricts the number to be the only thing on the line.
In the other one, \b means a word boundary, so it just means no other letters or digits may come directly before or after the number.
Also, note, in your original regex, the {1} is redundant, and [\d] means the same as \d.
^3538{1}[\d]{8}[^\d] will ensure you have 3538 followed by 8 digits and something that is NOT a digit -- thus limiting the length.
Add a dollar sign ($) at the end of the regex:
^3538{1}[\d]{8}$