I am having trouble with a negative lookahead in JavaScript. This may seem like a silly thing to regex, but it's still something I'm trying to figure out.
Say I have the following string:
>>a+b+c
and I know that the first two characters (a,b) can be in any order, but the last character (c) must be last. The characters cannot be repeated, and all characters must be separated by a plus (+).
I am using a negative lookahead in the following manner:
^>>(?:([ab+])(?!.*\1))*$
Testing the following strings works until this point:
>>a+b //true, as expected
>>b+a //true, as expected
However, when I try to move beyond the negative lookahead, I can't seem to get things to work:
^>>(?:([ab+])(?!.*\1))*\+c$
Test the following strings:
>>a+b+c //false, expecting true
>>b+a+c //false, expecting true
What am I not understanding?
Your problem is that your capture matches the single + in the pattern which then cannot be repeated (that is, the repetition of + in your input makes the match fail).
Try this regex instead:
^>>(?:([ab])\+(?!.*\1))*c$
Try adding a . before your last *. You want to match characters after doing the lookahead check, not match 0 or more of the whole check. (Assuming you only want a+b+c or b+a+c to match, although if those are the only to combos, you might just literally match those two with an or.)
^>>(?:([ab+])(?!.*\1)).*\+c$
I believe that will also match just a+c so this might be what you want instead:
^>>(?:([ab])\+(?!\1)).\+c$
Related
I have been trying to make a regex that will: match only if all condition are met, will not match 1 to 10 or something like it and will ignore commas.
I have made (?=.*1)(?=.*5) which almost works and will match to 1,5 as it is meant to but will also match to 10,5,10,50 and 1,50. I can not work out how to stop this. So my question is how do I get the regex to know the difference between numerals and a single digit.
Make it match word boundaries around the number, using \b.
(?=.*\b1\b)(?=.*\b5\b)
I'm trying to match strings that do not fit the pattern name (CA) or barbaz (UK). I seem to have solved the problem using the answer here, but this is what I started with, and I'm wondering why it doesn't work:
var r1 = /^.+(?!\([A-Z]{2}\))$/;
r1.test('foo'); //true
r1.test('foo (US)'); //whoops -also true
From reading a negated lookahead doc I was hoping that any string that is not followed by e.g. (JP) would result in a match, while anything that is followed by e.g. (DE) would fail. (Only the former is being met).
I thought perhaps the .+ was kind of "consuming" everything, nullifying the lookahead, so I tried
r2 = /^[^()]+(?!\([A-Z]+\))$/;
r2.test('name (US)'); //false
r2.test('foo('); //whoops -also false
However I need things like foo( to match.
Why did my first attempt fail?
In your first expression, the .+ consumes the whole string and then the look-ahead is tested - it doesn't match, as there are no characters left. To achieve your goal you can use /^(?!.+\([A-Z]{2}\)$).+$/ - first checking the non-presence of the unwanted construct, then matching.
See https://regex101.com/r/aG7xZ0/1 with your samples
I'm trying to write a regular expression to match amounts. In my case, what I need is that either the amount should be a positive integer or if the decimal is used, it must be followed by one or two integers. So basically, the following are valid amounts:
34000
345.5
876.45
What I wrote was this: /[0-9]+(\.[0-9]{1,2}){0,1}/
My thinking was that by using parenthesis like so: (\.[0-9]{1,2}), I would be able to bundle the whole "decimal plus one or two integers" part. But it isn't happening. Among other problems, this regex is allowing stuff like 245. and 345.567 to slip through. :(
Help, please!
Your regular expression is good, but you need to match the beginning and end of the string. Otherwise, your regex can match only a portion of the string and still (correctly) return a match. To match the beginning of the string, use ^, for the end, use $.
Update: as Avinash has noted, you can replace {0,1} with ?. JS supports \d for digits, so the regex can be further simplified
Finally, since if are only testing against a regex, you can use a non-capturing group ( (?:...) instead of (...)), which offers better performance.
original:
/[0-9]+(\.[0-9]{1,2}){0,1}/.test('345.567')
Fixed, and faster ;)
/^\d+(?:\.\d{1,2})?$/.test('345.567')
This is my string:
<address>tel+1234567890</address>
This is my regex:
([\d].*<)
which matches this:
1234567890<
but I dont want to match the last <character.
You can use a positive lookahead:
\d+(?=<)
The (?=...) syntax makes sure what's inside the parens matches at that position, without moving the match cursor forward, thus without consuming the input string. It's also called a zero-width assertion.
By the way, the square brackets in [\d] are redundant, so you can omit them. Also, I've changed the regex, but perhaps you really meant to match this:
\d.*?(?=<)
This pattern matches everything between a digit and a <, including the digit. It makes use of an ungreedy quantifier (*?) to match up until the first < if there are several.
([\d]+)
This should work , try it out and let me know
Check the demo
Also as #LucasTrzesniewski said , you can use the look ahead
(\d+.(?=<))
Here is the demo
We had a developer here who had added following line of code to a web application:
var amount = newValue.replace(/[^\d.-]/g, '');
The particular line deals with amount values that a user may enter into a field.
I know the following about the regular expression:
that it replaces the matches with empty strings (i.e. removes them)
that /g is a flag that means to match all occurrences inside "newValue"
that the brackets [] denote a special group
that ^ means beginning of the line
that d means digits
Unfortunately I do not know enough to determine what kind of strings this should match. I checked with some web-based regex testers if it matches e.g. strings like 98.- and other alternatives with numbers but so far no luck.
My problem is that it seems to make IE very slow so I need to replace it with something else.
Any help on this would be appreciated.
Edit:
Thanks to all who replied. I tried not just Google but sites like myregextester.com, regular-expressions.info, phpliveregex.com, and others. My problem was misunderstanding the meaning of ^ and expecting that this required a numeric string like 44.99.
Inside the group, when the ^ is the first character, it works as a negation of the character matches. In other words, it's saying match any character that are not the ones in the group.
So this will mean "match anything that is not a digit, a period, or a hyphen".
The ^ character is a negation character.
var newValue = " x44x.-x ";
var amount = newValue.replace(/[^\d.-]/g, '');
console.log(amount);
will print
44.-
I suspect the developer maybe just wanted to remove trailing whitespaces? I would rather try to parse the string for numbers and remove anything else.