How to group expressions to be matched as one? - regex

What i am trying to match is like this :
char-char-int-int-int
char-char-char-int-int-int
char-char-int-int-int-optionnalValue (optionalValue being a "-" plus letters after it
My current regep looks like this :
([A-Za-z]{1,2})([1-9]{3})("-"[\w])
In the end, the regexp should match any of these:
AB001
aB999
Hm000
en789
rv005-ab
These should be invalid:
ab (because only letters)
abcfr (because too much letters)
158 (because only numbers)
78532 (because too much numbers)
123ab (because all letters should come before numbers, optionalValue exepted)
a1b23 (because letters and numbers are mixed)
What am i doing wrong ? (please be gentle this is my first post ever on stackoverflow)

If you use [A-Za-z]{1,2} then the second example would not match as there a 3 char-char-char
Using \w would also match numbers and an underscore. If you mean letters like a-zA-Z you can use that in an optional group preceded by a hyphen (?:-[a-zA-Z]+)?
You could use
^[a-zA-Z]{2,3}[0-9]{3}(?:-[a-zA-Z]+)?$
^ Start of string
[a-zA-Z]{2,3} Match 2 or 3 times a char A-Za-z
[0-9]{3} Match 3 digits
(?:-[a-zA-Z]+)? Optionally match a - and 1 or more chars A-Za-z
$ End of string
Regex demo
Or using word boundaries \b instead of anchors
\b[a-zA-Z]{2,3}[0-9]{3}(?:-[a-zA-Z]+)?\b
Regex demo

I have corrected your regex below. Please give it a try.
([A-Za-z]{1,2})([0-9]{3})(-\w*)?
Demo

Related

Find certain colons in string using Regex

I'm trying to search for colons in a given string so as to split the string at the colon for preprocessing based on the following conditions
Preceeded or followed by a word e.g A Book: Chapter 1 or A Book :Chapter 1
Do not match if it is part of emoticons i.e :( or ): or :/ or :-) etc
Do not match if it is part of a given time i.e 16:00 etc
I've come up with a regex as such
(\:)(?=\w)|(?<=\w)(\:)
which satisfies conditions 2 & 3 but still fails on condition 3 as it matches the colon present in the string representation of time. How do I fix this?
edit: it has to be in a single regex statement if possible
You can use
(:\b|\b:)(?!(?:(?<=\b\d:)|(?<=\b\d{2}:))\d{1,2}\b)
See the regex demo. Details:
(:\b|\b:) - Group 1: a : that is either preceded or followed with a word char
(?!(?:(?<=\b\d:)|(?<=\b\d{2}:))\d{1,2}\b) - there should be no one or two digits right after : (followed with a word boundary) if the : is preceded with a single or two digits (preceded with a word boundary).
Note :\b is equal to :(?=\w) and \b: is equal to (?<=\w):.
If you need to get the same capturing groups as in your original pattern, replace (:\b|\b:) with (?:(:)\b|\b(:)).
More flexible solution
Note that excluding matches can be done with a simpler pattern that matches and captures what you need and just matches what you do not need. This is called "best regex trick ever". So, you may use a regex like
8:|:[PD]|\d+(?::\d+)+|(:\b|\b:)
that will match 8:, :P, :D, one or more digits and then one or more sequences of : and one or more digits, or will match and capture into Group 1 a : char that is either preceded or followed with a word char. All you need to do is to check if Group 1 matched, and implement required extraction/replacement logic in the code.
Word characters \w include numbers [a-zA-Z0-9_]
So just use [a-ZA-Z] instead
(\:)(?=[a-zA-Z])|(?<=[a-zA-Z])(\:)
Test Here

Regular Expression to extract alphanumeric parts of a URL?

Given any URL, like:
https://stackoverflow.com/v1/summary/1243PQ/details/P1/9981
How do I extract the numeric or alphanumeric part of the URL? I.e. the following strings from the url given above:
1. v1
2. 1243PQ
3. P1
4. 9981
To rephrase, a regex to extract strings from a string (URL) which have at least 1 digit and 0 or more alphabet characters, separated by '/'.
I tried to capture a repeating group (^[a-zA-Z0-9]+)+ and ([a-zA-Z]{0,100}[0-9]{1,100})+ but it didn't work. In hindsight intuition does say this shouldn't work. I am unsure how do I match patterns over a group and not just a single character.
If I understand what you really want:
Extracting parts with only numbers or with numbers following alphabets
then; I can suggest this regex:
\b[a-zA-Z]*[0-9]+[a-zA-z]*\b
Regex Demo
I use \b to assert position of a word boundary or a part.
As numbers are required and alphabets can comes before or after that I use above regex.
If following alphabets are not required then I can suggest this regex:
\b[a-zA-z0-9]*[0-9]+[a-zA-Z0-9]*\b
Regex Demo
I believe this should work for you:
(\d*\w+\d+\w*)
EDIT: actually, this should be sufficient
(\w+\d+\w*)
or
(\w*\d+\w*)
Well, you could do this:
(\w*\d+\w*) with the g (global) regex option
On the example URL, it would look like this:
const regex = /(\w*\d+\w*)/g;
const url = 'https://stackoverflow.com/v1/summary/1243PQ/details/P1/9981';
console.log(url.match(regex))
Try \/[a-zA-Z]*\d+[a-zA-Z0-9]*
Explanation:
\/ - match / literally
[a-zA-Z]* - 0+ letters
\d+ - 1+ digits - thanks to this, we require at least one digits
[a-zA-Z0-9]* - 0+ letters or digits
Demo
It will captrure together with / at the beginning, so you need to trim it.

Match only two combinations and ignore the rest in REGEX - tableau

I have a dozen input ID's and I need to match only two particular patterns while ignoring the rest. I have a column that would flag those valid/invalid if the regex match is true.
Test string:
1.) B-123456
2.) 985463728
My regex should strictly match the above two patterns and ignore the rest. The first test string would have an alphabet B followed by a hyphen and then few digits while the second test string is purely numbers. Below is what I tried:
[Bb\d][-\d][0-9]{1,9}
Please help me out with this as I have tried weird combinations and I am missing out on something tiny. My regex includes other combinations as well which should not happen.
You could match either bB a - and 6 digits, or match 9 digits surrounded by word boundaries:
\b(?:[Bb]-[0-9]{6}|[0-9]{9})\b
Regex demo
If the number of digits can vary, you could make the bB and the hyphen optional and either match 1+ digits using [0-9]+ or use a quantifier [0-9]{1,9}
\b(?:[bB]-)?[0-9]+\b
Or use anchors to assert the start ^ and the end $ of the string
^(?:[bB]-)?[0-9]+$

Regex to match a unlimited repeating pattern between two strings

I have a dataset with repeating pattern in the middle:
YM10a15b5c27
and
YM1b5c17
How can I get what is between "YM" and the last two numbers?
I'm using this but is getting one number in the end and should not.
/([A-Z]+)([0-9a-z]+)([0-9]+)/
Capture exactly two characters in the last group:
/([A-Z]+)([0-9a-z]+)([0-9]{2})/
You should use:
/^(?:([a-z]+))([0-9a-z]+)(?=\1)/
^ matches the start of the sentence. This is really important, because if your code is aaaa1234aaaa, then without the ^, it would also match the aaaa of the end.
(?:([a-z]+)) is a non-capturing group which takes any letter from 'a' to 'z' as group 1
(?=\1) tells the regex to match the text as long as it is followed by the same code at the starting.
All you have to do is extract the code by group(2)
An example is shown here.
Solution
If you want to match these strings as whole words, use \b(([a-z])\2)([0-9a-z]+)(\1)\b. If you need to match them as separate strings, use ^(([a-z])\2)([0-9a-z]+)(\1)$.
Explanation
\b - a word boundary (or if ^ is used, start of string)
(([a-z])\2) - Group 1: any lowercase ASCII letter, exactly two occurrences (aa, bb, etc.)
([0-9a-z]+) - Group 3: 1 or more digits or lowercase ASCII letters
(\1) - Group 4: the same text as stored in Group 1
\b - a word boundary (or if $ is used, end of string).

extract substring with regular expression

I have a string, actually is a directory file name.
str='\\198.168.0.10\share\ccdfiles\UA-midd3-files\UA0001A_15_Jun_2014_08.17.49\Midd3\y12m05d25h03m16.midd3'
I need to extract the target substring 'UA0001A' with matlab (well I would like think all tools should have same syntax).
It does not necessary to be exact 'UA0001A', it is arbitrary alphabet-number combination.
To make it more general, I would like to think the substring (or the word) shall satisfy
it is a alphabet-number combination word
it cannot be pure alphabet word or pure number word
it cannot include 'midd' or 'midd3' or 'Midd3' or 'MIDD3', etc, so may use case-intensive method to exclude word begin with 'midd'
it cannot include 'y[0-9]{2,4}m[0-9]{1,2}d[0-9]{1,2}\w*'
How to write the regular expression to find the target substring?
Thanks in advance!
You can use
s = '\\198.168.0.10\share\ccdfiles\UA-midd3-files\UA0001A_15_Jun_2014_08.17.49\Midd3\y12m05d25h03m16.midd3';
res = regexp(s, '(?i)\\(?![^\W_]*(midd|y\d+m\d+))(?=[^\W_]*\d)(?=[^\W_]*[a-zA-Z])([^\W_]+)','tokens');
disp(res{1}{1})
See the regex demo
Pattern explanation:
(?i) - the case-insensitive modifier
\\ - a literal backslash
(?![^\W_]*(midd|y\d+m\d+)) - a negative lookahead that will fail a match if there are midd or y+digits+m+digits after 0+ letters or digits
(?=[^\W_]*\d) - a positive lookahead that requires at least 1 digit after 0+ digits or letters ([^\W_]*)
(?=[^\W_]*[a-zA-Z]) - there must be at least 1 letter after 0+ letters or digits
([^\W_]+) - Group 1 (what will extract) matching 1+ letters or digits (or 1+ characters other than non-word chars and _).
The 'tokens' "mode" will let you extract the captured value rather than the whole match.
See the IDEONE demo
this should get you started:
[\\](?i)(?!.*midd.*)([a-z]+[0-9]+[a-z0-9]*|[a-z]+[0-9]+[a-z0-9]*)
[\\] : match a backslash
(?i) : rest of regex is case insensitive
?! following match can not match this
(?!.*midd.*) : following match can not be a word wich has any character, midd, any character
([a-z]+[0-9]+[a-z0-9]*|[a-z]+[0-9]+[a-z0-9]*) match at least one number followed by at least one letter OR at least one letter followed by at least one number followed by any amount of letters and numbers (remember, cannot match the ?! group so no word which contains mid )