Within Livecycle, I am validating that the number entered is a 0 through 10 and allows quarter hours. With the help of this post, I've written the following.
if (!xfa.event.newText.match(/^(([10]))$|^((([0-9]))$|^((([0-9]))\.?((25)|(50)|(5)|(75)|(0)|(00))))$/))
{
xfa.event.change = "";
};
The problem is periods are not being accepted. I have tried wrapping the \. in parenthesis but that did not work either. The field is a text field with no special formatting and the code in the change event.
Yikes, that's a convoluted regex. This can be simplified a lot:
/^(?:10|[0-9](?:\.(?:[27]?5)?0*)?)$/
Explanation:
^ # Start of string
(?: # Start of group:
10 # Either match 10
| # or
[0-9] # Match 0-9
(?: # optionally followed by this group:
\. # a dot
(?:[27]?5)? # either 25, 75 or 5 (also optional)
0* # followed by optional zeroes
)? # As said before, make the group optional
) # End of outer group
$ # End of string
Test it live on regex101.com.
Related
I'm trying to build a regex pattern matcher.
The complete string pattern is as follow:
AB123456C12
Letter A
Letter B
six digits
one letter
two digits.
I'm trying to match as much as possible, but partial inputs are allowed as long as the initial AB is present.
The RegEx engine is Javascript. Hoping to be fully cross-browser compatible.
I do have a pattern that works:
^AB([0-9]{6}[A-Z][0-9]{0,2}|[0-9]{0,6})$
But it only works when the arguments of the alternation operator are in this position. Said otherwise,
^AB([0-9]{0,6}|[0-9]{6}[A-Z][0-9]{0,2})$
doesn't work - which makes me believe that the solution may not work in some obscure browser.
So, any other way to define that pattern?
Thanks.
Edited for clarity: the followings are inputs that must be matched by the regex:
AB
AB123
AB123456Z
The followings input are to be rejected:
B
B123456Z12
ABC
123456
This may help
^AB[0-9]{6}[A-Z][0-9]{2}$
I think you are looking for this.
# ^AB(?:(?:[0-9]{6}(?:[A-Z][0-9]{0,2})?)|[0-9]{1,5})?$
^ # BOS
AB # AB
(?: # Optional cl-1
(?: # Required cl-2
[0-9]{6} # Required 6 digits
(?: # Optional cl-3
[A-Z] # Required A-Z letter
[0-9]{0,2} # Required 0-2 (0 means optional)
)? # End cl-3
) # End cl-2
| # or
[0-9]{1,5} # Required 1-5 digits
)? # End cl-1
$ # EOS
I've been at this for too long, trying to figure out how to match a comma-delimited string of values, while breaking apart the values into their own capturing groups. Here are my requirements:
No leading comma
Terms can be alphanumeric, with between 1 and 7 characters
Min: 1 term; Max: unlimited
Unlimited whitespace between terms and commas
No trailing comma
I'm so close, but I'm not able to get all terms in the string into their own capture groups. Instead it places the last matched term from the first capturing group into group #1, instead of placing all matches into previous groups. So here's my example:
abc1234, def5678, ghi9012
I would expect abc1234 to be group #1, def5678 to be group #2, and ghi9012 to be group #3. Instead, using the expression below, I get def5678 in group #1 and ghi9012 in group #2.
/(?:([A-z0-9]{1,7})\s*,\s*)+([A-z0-9]{1,7})/g
Link to RegExr example
I'm pretty sure I haven't set up my capturing/non-capturing groups correctly. Any help would be greatly appreciated.
This can do it for you. Using the extraction regex the value is in group 1. Also the value is trimmed.
Let me know if you need one for quoted fields.
Note that the requirement for 1-7 chars can't be enforced using the extraction one,
unless its validated ahead of time.
Validation regex:
# /^(?:(?:(?:^|,)\s*)[a-zA-Z0-9]{1,7}(?:\s*(?:(?=,)|$)))+$/
^
(?:
(?: # leading comma + optional whitespaces
(?: ^ | , )
\s*
)
[a-zA-Z0-9]{1,7} # alpha-num, 1-7 chars
(?: # trailing optional whitespaces
\s*
(?:
(?= , )
| $
)
)
)+
$
Extraction regex.
# /(?:(?:^|,)\s*)([^,]*?)(?:\s*(?:(?=,)|$))/
(?: # leading comma + optional whitespaces
(?: ^ | , )
\s*
)
( [^,]*? ) # (1), non-quoted field
(?: # trailing optional whitespaces
\s*
(?:
(?= , )
| $
)
)
I have this regular expression
/^[',",\+,<,>,\(,\*,\-,%]?([£,$,€]?\d+([\,,\.]\d+)?[£,$,€]?\s*[\-,\/,\,,\.,\+]?[\/]?\s*)+[',",\+, <,>,\),\*,\-,%]?$/
It matches this very well $55.5, but in few of my test data I have some values like $ 55.5 (I mean, it has a space after $ sign).
The answers on this link are not working for me.
Currency / Percent Regular Expression
So, how can I change it to accept the spaces as well?
Try following RegEx:
/^[',",\+,<,>,\(,\*,\-,%]?([£,$,€]?\s*\d+([\,,\.]\d+)?[£,$,€]?\s*[\-,\/,\,,\.,\+]?[\/]?\s*)+[',",\+, <,>,\),\*,\-,%]?$/
Let me know if it worked!
Demo Here
TLDR:
/^[',",\+,<,>,\(,\*,\-,%]?([£,$,€]?\s*\d+([\,,\.]\d+)?[£,$,€]?\s*[\-,\/,\,,\.,\+]?[\/]?\s*)+[',",\+, <,>,\),\*,\-,%]?$/
The science bit
Ok, I'm guessing that you didn't construct the original regular expression, so here are the pieces of it, with the addition marked:
^ # match from the beginning of the string
[',",\+,<,>,\(,\*,\-,%]? # optionally one of these symbols
( # start a group
[£,$,€]? # optionally one of these symbols
\s* # <--- NEW ADDITION: optionally one or more whitespace
\d+ # then one or more decimal digits
( # start group
[\,,\.] # comma or a dot
\d+ # then one or more decimal digits
)? # group optional (comma/dot and digits or neither)
[£,$,€]? # optionally one of these symbols
\s* # optionally whitespace
[\-,\/,\,,\.,\+]? # optionally one of these symbols
[\/]? # optionally a /
\s* # optionally whitespace
)+ # this whole group one or more times
[',",\+, <,>,\),\*,\-,%]? # optionally one of these symbols
$ # match to the end of the string
Much of this is poking about matching stuff around the currency amount, so you could reduce that.
I'm trying to use a URL matching regular expression that I got from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
(?xi)
\b
( # Capture 1: entire matched URL
(?:
https?:// # http or https protocol
| # or
www\d{0,3}[.] # "www.", "www1.", "www2." … "www999."
| # or
[a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash
)
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
(?: # End with:
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
| # or
[^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars
)
)
Based on the answers to another question, it appears that there are cases that cause this regex to backtrack catastrophically. For example:
var re = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i;
re.test("http://google.com/?q=(AAAAAAAAAAAAAAAAAAAAAAAAAAAAA)")
... can take a really long time to execute (e.g. in Chrome)
It seems to me that the problem lies in this part of the code:
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
... which seems to be roughly equivalent to (.+|\((.+|(\(.+\)))*\))+, which looks like it contains (.+)+
Is there a change I can make that will avoid that?
Changing it to the following should prevent the catastrophic backtracking:
(?xi)
\b
( # Capture 1: entire matched URL
(?:
https?:// # http or https protocol
| # or
www\d{0,3}[.] # "www.", "www1.", "www2." … "www999."
| # or
[a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash
)
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
(?: # End with:
\(([^\s()<>]|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
| # or
[^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars
)
)
The only change that was made was to remove the + after the first [^\s()<>] in each of the "balanced parens" portions of the regex.
Here is the one-line version for testing with JS:
var re = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i;
re.test("http://google.com/?q=(AAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
The problem portion of the original regex is the balanced parentheses section, to simplify the explanation of why the backtracking occurs I am going to completely remove the nested parentheses portion of it because it isn't relevant here:
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # original
\(([^\s()<>]+)*\) # expanded below
\( # literal '('
( # start group, repeat zero or more times
[^\s()<>]+ # one or more non-special characters
)* # end group
\) # literal ')'
Consider what happens here with the string '(AAAAA', the literal ( would match and then AAAAA would be consumed by the group, and the ) would fail to match. At this point the group would give up one A, leaving AAAA captured and attempting to continue the match at this point. Because the group has a * following it, the group can match multiple times so now you would have ([^\s()<>]+)* matching AAAA, and then A on the second pass. When this fails an additional A would be given up by the original capture and consumed by the second capture.
This would go on for a long while resulting in the following attempts to match, where each comma-separated group indicates a different time that the group is matched, and how many characters that instance matched:
AAAAA
AAAA, A
AAA, AA
AAA, A, A
AA, AAA
AA, AA, A
AA, A, AA
AA, A, A, A
....
I may have counted wrong, but I'm pretty sure it adds up to 16 steps before it is determined that the regex cannot match. As you continue to add additional characters to the string the number of steps to figure this out grows exponentially.
By removing the + and changing this to \(([^\s()<>])*\), you would avoid this backtracking scenario.
Adding the alternation back in to check for the nested parentheses doesn't cause any problems.
Note that you may want to add some sort of anchor to the end of the string, because currently "http://google.com/?q=(AAAAAAAAAAAAAAAAAAAAAAAAAAAAA" will match up to just before the (, so re.test(...) would return true because http://google.com/?q= matches.
I need to validate and input string client side.
Here is an example of the string:
1:30-1:34, 1:20-1:22, 1:30-1:37,
It's basically time codes for a video.
Can this be done with regex?
Banging my head against the wall...
^(?:\b\d+:\d+-\d+:\d+\b(?:, )?)+$
would probably work; at least it matches your example. But you might need to add a few edge cases to make the rules for matching/not matching clearer.
^ # Start of string
(?: # Try to match...
\b # start of a "word" (in this case, number)
\d+ # one or more digits
: # a :
\d+ # one or more digits
- # a dash
\d+ # one or more digits
: # a :
\d+ # one or more digits
\b # end of a "word"
(?:, )? # optional comma and space
)+ # repeat one or more times
$ # until the end of the string
The following is a simple representation. I have assumed that the string has the exact same form as you have shown. This may be a good starting point for you. I'll improve the regex if you provide more specific requirements.
([0-9]+:[0-9]{1,2}-[0-9]+:[0-9]{1,2},\w*)+
Explanation (inspired from Tim above)
[0-9]+ #One ore more digits
: # A colon
[0-9]{1,2} #A single digit or a pair of digits
- #A dash
, #A comma
\w* #Optional whitespace