I've been trying to use RegExp in JS to test a string for a certain count of a substrings. I would like a purely RegExp approach so I can combine it with my other search criteria, but have not had any luck.
As a simple example I would like to test a word if it has exactly 2-3 as.
case
test string
expected result
1
cat
false
2
shazam
true
3
abracadabra
false
Most of my guesses at regex fail case 3. Example: ^(?<!.*a.*)((.*a.*){2,3})(?!.*a.*)$
Could use this regex.
With any other character, including whitespace.
^[^a]*(?:a[^a]*){2,3}$
or if using multi-lines and don't want to span.
^[^a\r\n]*(?:a[^a\r\n]*){2,3}$
^ # Begin
[^a]* # optional not-a
(?: # Grp
a # single a
[^a]* # optional not-a
){2,3} # Get 2 or 3 a only
$ # End
https://regex101.com/r/O3SYKx/1
Related
I am trying to test a Regex which should be able to split the following expressions into 3 parts:
test
true
false
If there are multiple iif nested, it should give me multiple matches
And I have some patterns:
iif(testExpression, trueExpression, falseExpression)
iif((#HasMinimunRegulatedCAR#==0),(([t219]>1.5) OR ([t219]<-0.5)),(([t223]>1.5) OR ([t223]<-0.5)))
iif((#HasMinimunRegulatedCAR#==1), iif((#MFIUsePAR30#==1), ([t224]>0.25), iif((#MFIUsePAR90#==1), ([t225]>0.25), (1==1))), iif((#MFIUsePAR30#==1), ([t220]>0.25), iif((#MFIUsePAR90#==1), ([t221]>0.25),(1==1))))
I am using this expression but it doesn't work when I have multiple iif nested
(^(iif\()|[^,]+)
I am running my tests using:
https://regex101.com/
The expected output should be
testExpression
trueExpression
falseExpression
(#HasMinimunRegulatedCAR#==0)
([t219]>1.5) OR ([t219]<-0.5)
([t223]>1.5) OR ([t223]<-0.5)
(#HasMinimunRegulatedCAR#==1)
iif((#MFIUsePAR30#==1), ([t224]>0.25), iif((#MFIUsePAR90#==1), ([t225]>0.25), (1==1)))
iif((#MFIUsePAR30#==1), ([t220]>0.25), iif((#MFIUsePAR90#==1), ([t221]>0.25),(1==1)))
If .Net regular expressions are an option, you can use balancing groups to capture your iifs.
One option will capture all nested parentheses into a group called Exp:
(?>
(?:iif)?(?<Open>\((?<Start>)) # When seeing an open parenthesis, mark
# a beginning of an expression.
# Use the stack Open to count our depth.
|
(?<-Open>(?<Exp-Start>)\)) # Close parenthesis. Capture an expression.
|
[^()\n,] # Match any regular character
|
(?<Exp-Start>),(?<Start>) # On a comma, capture an expression,
# and start a new one.
)+?
(?(Open)(?!))
Working Example, switch to the Table tab.
This option captures more than you ask for, but it does give you the full data you need to fully parse the equation.
Another option is to capture only the top-level parts:
iif\(
(?:
(?<TopLevel>(?>
(?<Open>\() # Increase depth count using the Open stack.
|
(?<-Open>\)) # Decrease depth count.
|
[^()\n,]+ # Match any other boring character
|
(?(Open),|(?!)) # Match a comma, bun only if we're already inside parentheses.
)+)
(?(Open)(?!))
|
,\s* # Match a comma between top-level expressions.
)+
\)
Working Example
Here, the group $TopLevel will have three captures. For example, on your last example, it captures:
Capture 0: (#HasMinimunRegulatedCAR#==1)
Capture 1: iif((#MFIUsePAR30#==1), ([t224]>0.25), iif((#MFIUsePAR90#==1), ([t225]>0.25), (1==1)))
Capture 2: iif((#MFIUsePAR30#==1), ([t220]>0.25), iif((#MFIUsePAR90#==1), ([t221]>0.25),(1==1)))
I've got a text box where I wanted to ensure some goods and bads out of it.
For instance good could include:
GoodString
GoodString88
99GoodString
Some bad things I did not want to include was:
Good*String
Good&String
But one thing I wanted to allow would be to allow spaces between words so this should of been good:
Good String
However my regex/js is stating this is NOT a good string - I want to allow it. I'm using the test routine for this and I'm as dumb as you can get with regexes. I don't know why I can never understand these things...
In any event my validation is as follows:
var rx = /^[\w.-]+$/;
if (!rx.test($("#MainContent_txtNewDocumentTitle").val())) {
//code for bad string
}else{
//code for good string
}
What can I do to this:
var rx = /^[\w.-]+$/;
Such that spaces are allowed?
You can use this regex instead to allow space only in middle (not at start/end):
var rx = /^[\w.-]+(?:[ \t]+[\w.-]+)*$/gm;
RegEx Demo
RegEx Breakup:
^ # line start
[\w.-]+ # match 1 or more of a word character or DOT or hyphen
(?: # start a non-capturing group
[ \t]+ # match one or more space or tab
[\w.-]+ # match 1 or more of a word character or DOT or hyphen
)* # close the non-capturing group. * will allow 0 or more matches of group
$ # line end
/gm # g for global and m for multiline matches
RegEx Reference
var string = 'Our Prices are $355.00 and $550, down form $999.00';
How can I get those 3 prices into an array?
The RegEx
string.match(/\$((?:\d|\,)*\.?\d+)/g) || []
That || [] is for no matches: it gives an empty array rather than null.
Matches
$99
$.99
$9.99
$9,999
$9,999.99
Explanation
/ # Start RegEx
\$ # $ (dollar sign)
( # Capturing group (this is what you’re looking for)
(?: # Non-capturing group (these numbers or commas aren’t the only thing you’re looking for)
\d # Number
| # OR
\, # , (comma)
)* # Repeat any number of times, as many times as possible
\.? # . (dot), repeated at most once, as many times as possible
\d+ # Number, repeated at least once, as many times as possible
)
/ # End RegEx
g # Match all occurances (global)
To match numbers like .99 more easily I made the second number mandatory (\d+) while making the first number (along with commas) optional (\d*). This means, technically, a string like $999 is matched with the second number (after the optional decimal point) which doesn’t matter for the result — it’s just a technicality.
A non-regex approach: split the string and filter the contents:
var arr = string.split(' ').filter(function(val) {return val.startsWith('$');});
Use match with regex as follow:
string.match(/\$\d+(\.\d+)?/g)
Regex Explanation
/ : Delimiters of regex
\$: Matches $ literal
\d+: Matches one or more digits
()?: Matches zero or more of the preceding elements
\.: Matches .
g : Matches all the possible matching characters
Demo
This will check if there is a possible decimal digits following a '$'
i am using ^(^[a-z]?[a0-z9]+[.|-][a0-z9]+[a-z]+[.|-][a0-z9]+[a-z]?$)+$ , this force user type 2 hyphen(-) in his expression ....
But i need that regular expression can allow maximum 2 hypen and minimum one hyphen in his expression....
This is a simple re implementation.
/^[^-]+(-[^-]+){1,2}$/
And the test result:
"123".match(/^[^-]+(-[^-]+){1,2}$/)
null
"123-123".match(/^[^-]+(-[^-]+){1,2}$/)
["123-123", "-123"]
"123-123-123".match(/^[^-]+(-[^-]+){1,2}$/)
["123-123-123", "-123"]
"123-123-123-123".match(/^[^-]+(-[^-]+){1,2}$/)
null
And if you just copy one from other, then you should try to write one by yourself.
If not, you should delete it and restart.
^[^-]*-+[^-]*-{0,1}[^-]*$
String1: abc-pqr,
String2: aaa-bbb,
String3 aaa-bbb-ccc-ddd,
where String 1 and 2 are valid and 3 is invalid?
This allows String 1 and 2. But not 3.
This regex should work...
/^[^-]*-[^-]*-[^-]*$/
It works by capturing anything except a hyphen (zero or more times), then a hyphen, then anything else again, then another hyphen, then anything else. It has a start and end marker to ensure that the whole string does not contain any more hyphens.
Breaks down like this...
/ # begin regex
^ # start of string
[^-]* # not hyphen ([^-]), zero or more times (*)
- # hyphen
[^-]* # not hyphen ([^-]), zero or more times (*)
- # hyphen
[^-]* # not hyphen ([^-]), zero or more times (*)
$ # end of string
/ # end regex
Can someone help me to validate the following rules using a RegEx pattern
Max length : 15
Minimum length : 6
Minimum character count : 1
Minimum numbers count : 1
Consequent repeated character count : 2
^ # start of string
(?=.{6,15}$) # assert length
(?=.*[A-Za-z]) # assert letter
(?=.*[0-9]) # assert digit
(?:(.)(?!\1\1))* # assert no more than 2 consecutive characters
$ # end of string
will do this. But this won't look nice (or easily maintainable) in JavaScript:
if (/^(?=.{6,15}$)(?=.*[A-Za-z])(?=.*[0-9])(?:(.)(?!\1\1))*$/.test(subject)) {
// Successful match
} else {
// Match attempt failed
}
I suggest you use a few different regex patterns to check for all those rules cause it will either be impossible or very complicated.
.length to check the first 2 rules
[a-z] (with case insensitive option) for the 3rd rule
\d for the 4th rule
(.)\1{2,} for the 5th rule, if this one matches the string contains 3+ character repetitions