perl regular expression digit match - regex

Doing the below regex match to verify whether date is in the YYYY_MM_DD Format. But the regular expression gives an error message if i have a value of 2012_07_7. Date part and month should be exactly 2 digits according to the regex pattern. Not sure why it's not working.
if ($cmdParams{RunId} !~ m/^\d{4}_\d{2}_\d{2}$/)
{
print "Not a valid date in the format YYYY_MM_DD";
}

Your regex specifies exactly 2 digits for the day component, if you want to allow either 1 or 2 digits you should use {1,2} rather than {2}

Well if you look at your data that you have: 2012_07_7 you can see that the day-part is not of two digits.

Obviously. Your pattern dictates that the last numeric chunk should be of two digits, whereas you are providing 1. So if you want your pattern to match this text, try something like:
if ($cmdParams{RunId} !~ m/^\d{4}_\d{2}_\d\d?$/)

My solution: ^\d{4}_(?:1[0-2]|0?[1-9])_(?:3[01]|[1-2]\d|0?[1-9])$
this pattern match: 2000_12_01 or 2001_1_1 or 2001_02_1

Related

Is it possible to negate a group in a regular expression?

Let's say that we have this text:
2020-09-29
2020-09-30
2020-10-01
2020-10-02
2020-10-12
2020-10-16
2020-11-12
2020-11-23
2020-11-15
2020-12-01
2020-12-11
2020-12-30
I want to do something like this:
\d\d\d\d-(NOT10)-(30)
So i want to get all dates of any year, but not of the 10th month and it is important, that the day is 30.
I tried a lot to do this using negative lookahead asserations but i did not come up with any working regexes.
You can use negative lookaheads:
\d\d\d\d-(?!10)\d\d-30
The Part (?!10) ensures that no 10 follows at the point where it is inserted into the regex. Notice that you still need to match the following digits afterwards, thus the \d\d part.
Generally speaking you can not (to my knowledge) negate a part that then also matches parts of the string. But with negative lookaheads you can simulate this as I did above. The generalized idea looks something like:
(?!<special-exclusion-pattern>)<general-inclusion-pattern>
Where the special-exclusion-pattern matches a subset of the general-inclusion-pattern. In the above case the general inclusion pattern is \d\d and the special exclusion pattern ins 10.
Try :
/20\d{2}-(?:0[1-9]|1[12])-30/
Explanation :
20\d{2} it will match 20XX
(?:0[1-9]|1[12]) it will match 0X or 11, 12
30 it will match 30
Demo :https://regex101.com/r/O2F1eV/1
It's easiest to simply convert the substring (if present) that matches /^\d{4}-10-30$/ to an empty string, then split the resulting string on one or more newlines.
If your string were
2020-10-16
2020-10-30
2020-11-12
2020-11-23
and was held by the variable str, then in Ruby, for example,
str.sub(/^\d{4}-10-30$/,'')
#=> "2020-10-16\n\n2020-11-12\n2020-11-23\n"
so
str.sub(/^\d{4}-10-30$/,'').split
#=> ["2020-10-16", "2020-11-12", "2020-11-23"]
Whatever language you are using undoubtedly has similar methods.

Parse Number from string with regex

I have thousands of article descriptions containing numbers.
they look like:
ca.2760h3x1000.5DIN345x1500e34
the resulting numbers should be:
2760
1000.5
1500
h3 or 3 shall not be a result of the parsing, since h3 is a tolerance only
same for e34
DIN345 is a norm an needs to be excluded (every number with a trailing DIN or BN)
My current REGEX is:
[^hHeE]([-+]?([0-9]+\.[0-9]+|[0-9]+))
This solves everything BUT the norm. How can I get this "DIN" and "BN" treated the same way as a single character ?
Thanx, TomE
Try using this regular expression:
(?<=x)[+-]?0*[0-9]+(?:\.[0-9]+)?|[+-]?0*[0-9]+(?:\.[0-9]+)?(?=h|e)
It looks like every number in your testcase you want to match exept the first number is starting with x.This is what the first part of the regex matches. (?<=x)[+-]?0*[0-9]+(?:\.[0-9]+)?The second part of the regex matches the number until h or e. [+-]?0*[0-9]+(?:\.[0-9]+)?(?=h|e)
The two parts [+-]?0*[0-9]+(?:\.[0-9]+)? in the regex is to match the number.
If we can assume that the numbers are always going to be four digits long, you can use the regex:
(\d{4}\.\d+|\d{4})
DEMO
Depending on the language you might need to replace \d with [0-9].

Why my regex is failing for single digits but working for double digits?

I have the requirement to validate a String containing two numbers separated by a dash(-) or a comma(,). Valid values are :
23.98-34.76 or 23.98,34.76
23-34 or 23,34
5-6 or 5,6
I have the following regex which is a slight modification of the answer that I received here in SO. It is covering the 1st and 2nd case above but not the third case involving single digits only.
The modified regex String that I am using is :
(\d+\.?\d+?)([-,])(\d+\.?\d+?)
Where did my regex go wrong?
Correct regex should be like this:
(\d+(\.\d+)?)[-,](\d+(\.\d+)?)
i.e. if there is a period then it is always followed by 1 or more digits.
Otherwise in your regex it will also match strings like 123.,789.

How do I write a Regular Expression to match any three digit number value?

I'm working with some pretty funky HTML markup that I inherited, and I need to remove the following attributes from about 72 td elements.
sdval="285"
I know I can do this with find/replace in my code editor, except since the value of each attribute is different by 5 degree increments, I can't match them all without a Regular Expression. (FYI I'm using Esspress and it does support RegExes in it's Find/Replace tool)
Only trouble is, I really can't figure out how to write a RegEx for this value. I understand the concept of RegExes, but really don't know how to use them.
So how would I write the following with a Regular Expression in place of the digits so that it would match any three digit value?
sdval="285"
/sdval="\d{3}"/
EDIT:
To answer your comment, \d in regular expressions means match any digit, and the {n} construct means repeat the previous item n times.
Easiest, most portable: [0-9][0-9][0-9]
More "modern": \d{3}
This should do (ignores leading zeros):
[1-9][0-9]{0,2}
import re
data = "719"
data1 = "79"
# This expression will match any single, double or triple digit Number
expression = '[\d]{1,3}'
print(re.search(expression, data).string)
# This expression will match only triple digit Number
expression1 = '[\d]{3}'
print(re.search(expression1, data1).string)
Output :
expression : 719
expression1 : 79
It sounds like you're trying to do a find / replace in Visual Studio of a 3 digit number (references to Express and Find/Replace tool). If that's the case the regex to find a 3 digit number in Visual Studio is the following
<:d:d:d>
Breakdown
The < and > establish a word boundary to make sure we don't match a number subset.
Each :d entry matches a single digit.

What is wrong with this Regular Expression?

I am beginner and have some problems with regexp.
Input text is : something idUser=123654; nick="Tom" something
I need extract value of idUser -> 123456
I try this:
//idUser is already 8 digits number
MatchCollection matchsID = Regex.Matches(pk.html, #"\bidUser=(\w{8})\b");
Text = matchsID[1].Value;
but on output i get idUser=123654, I need only number
The second problem is with nick="Tom", how can I get only text Tom from this expresion.
you don't show your output code, where you get the group from your match collection.
Hint: you will need group 1 and not group 0 if you want to have only what is in the parentheses.
.*?idUser=([0-9]+).*?
That regex should work for you :o)
Here's a pattern that should work:
\bidUser=(\d{3,8})\b|\bnick="(\w+)"
Given the input string:
something idUser=123654; nick="Tom" something
This yields 2 matches (as seen on rubular.com):
First match is User=123654, group 1 captures 123654
Second match is nick="Tom", group 2 captures Tom
Some variations:
In .NET regex, you can also use named groups for better readability.
If nick always appears after idUser, you can match the two at once instead of using alternation as above.
I've used {3,8} repetition to show how to match at least 3 and at most 8 digits.
API links
Match.Groups property
This is how you get what individual groups captured in a match
Use look-around
(?<=idUser=)\d{1,8}(?=(;|$))
To fix length of digits to 6, use (?<=idUser=)\d{6}(?=($|;))