examples where the regex should return true: 1&&2, 1||2, 1&&2||3, 1
examples where the regex should return false: 1||, 1&&, &&2
My regex is:
[0-9]+([\\|\\|\\&&][0-9])*
but it returns true if the input is 1&&&2.
Where is my mistake?
Note that [\|\|\&&] matches a single | or & char, not || or && sequences of chars. Also, the [0-9] without a quantifier matches only one digit. Without anchors, you may match a string partially inside a longer string.
You may use
^[0-9]+(?:(?:\|\||&&)[0-9]+)*$
Actually, to match anywhere inside a string, keep on using the pattern without anchors:
[0-9]+(?:(?:\|\||&&)[0-9]+)*
See the regex demo
Details
^ - start of string
[0-9]+ - 1+ digits
(?:(?:\|\||&&)[0-9])* - 0 or more repetitions of
(?:\|\||&&) - || or && sequence of characters
[0-9]+ - 1+ digits
$ - end of string.
JS demo:
const reg = /^[0-9]+(?:(?:\|\||&&)[0-9]+)*$/;
console.log( reg.test('1||2') ); // => true
Related
i was trying to create a regex that could match numbers within brackets or not, for example:
(1.000.000,00) //match
(1.000,00) //match
(100,00) //match
(10) //match
(1) //match
(2.000.000,00 //dont't match
(2.000,00 //dont't match
(200,00 //dont't match
(20 //dont't match
(2 //dont't match
3.000.000,00) //dont't match
3.000,00) //dont't match
300,00) //dont't match
30) //dont't match
3) //dont't match
4.000.000,00 //should match
4.000,00 //should match
400,00 //should match
40 //should match
4 //should match
I need to match only numbers(in brackets or not), but only if they have all brackets (2) or none(0)
At the moment this is what i came up with: \((\d+[\.,]?)+\d*\), it matches the --match and doesn't match the --don't match but should match also the --should match
I've added the javascript tag because i'm using this regex in js and not all of the regex tokens work in the js regex constructor
I'm posting also a regex101 link
If supported, you can usea negative lookbehind to match either with or without parenthesis:
\(\d+(?:[.,]\d+)*\)|(?<!\S)\d+(?:[.,]\d+)*(?!\S)
\( Match (
\d+(?:[.,]\d+)* Match 1+ digits and optionally repeat matching . or , and again 1+ digits
\) Match )
| Or
(?<!\S) Negative lookbehind, assert a word boundary to the left
\d+(?:[.,]\d+)* Match 1+ digits and optionally repeat matching . or , and again 1+ digits
(?!\S) Negative lookahead, assert a whitespace boundary to the right
Regex demo
Another option could be matching optional parenthesis at both sides, and only keep the ones that have either an opening and closing parenthesis, or none.
const regex = /\(?\d+(?:[.,]?\d+)*\)?/
const strings = ["(1.000.000,00)", "(1.000,00)", "(100,00)", "(10)", "(1)", "(2.000.000,00", "(2.000,00", "(200,00", "(20", "(2", "3.000.000,00)", "3.000,00)", "300,00)", "30)", "3)", "4.000.000,00", "4.000,00", "400,00", "40", "4"];
strings.forEach(s => {
const m = s.match(regex);
const firstChar = s.charAt(0);
const lastChar = s.charAt(s.length - 1);
if (
m &&
(firstChar !== '(' && lastChar !== ')') ||
firstChar === '(' && lastChar === ')'
) {
console.log(s)
}
});
If you don't want to repeat the part matching numbers (which in this case is short, so maybe an exception to the DRY rule is warranted), you can reach for \(?((\d+[\.,]?)+\d*)\)?(?<=\(\1\)|(^|[^(\d.,])\1(?=($|[^\d.,)]))).
Edit: this is broken.
It will match numbers like (7 as it only matches the number and ignores the parentheses in that case.
Kept here for future reference.
It's usually easier to do regex in multiple passes, but here goes:
/(\((\d+[\.,]?)+\d*\))|(\d+[\.,]?\d*)/gm
You can test it on https://regex101.com/.
Usually it's better to process something in multiple passes as you can see the regex becomes even more unreadable.
I took your regex and just split it into two regexes: one that requires the parentheses and one that doesn't, then combined them with the or operator.
Note that this regex will allow things like "123.3,5.7" as one number, and the capturing groups will be nasty.
I am new to regular expression, In my project i am allowing user to put amount in shorthand as well as full digit, i have used material UI TextField for input.
Examples are:
400k - shorthand,
400.2k - shorthand,
4m - shorthand,
500. - should work
500000 - full amount
some pattern user should not be allowed to enter example are:
4.2.k,
.3k,
4...k
300.k
I have written regex which is below but it does allows to enter dot after number.
textValue.match(/^[0-9]*(\.[0-9]{0,2})*([0-9km]{1})$/) && textValue.match(/^[\d]+/)
above code first regex validates the pattern and second regex forces user to put Number because amount cannot start with string, i have wrote two separate regex as i don't understand how to put them in one regex and those regex doesn't accepts dot after number. Please can anyone give a perfect Regex to validate the above pattern in one single regular expression??
Thanks in advance
With alternation (never really the prettiest) it could be done like:
^\d+([km]|\.|\.\d+[km])?$
See the Online Demo
^ - Start string ancor.
d+ - One or more digits.
( - Opening capturing group (you could use non-capturing).
[km] - A single character "k" or "m".
| - Alternation (OR).
\.? - A literal dot.
| - Alternation (OR).
\.\d+[km] - A literal dot followed by at least one digit and a character "k" or "m".
)? - Close capturing group and make it optional
$ - Start string ancor.
About the pattern you tried
Note that you don't need {1}. The character class [0-9km] matches 1 of a char k or m or a digit 0-9. This way the possible digits to match could be 0-3 instead of 0-2.
Using the quantifier * for the group makes it possbile to also match 400.25.22.22.22k
You could use this pattern to validate the examples. The [0-9]+ at the beginning of the pattern makes sure that there has to be at least a single digit present.
If you want to allow 500. you could use:
^[0-9]+(?:(?:\.[0-9]{1,2})?[km]?|\.)$
Explanation
^ Start of string
[0-9]+ Match 1+ digits
(?: Non capture group
(?:\.[0-9]{1,2})? Match an optional decimal part with 2 digits
[km]? Match optional k or m
| Or
\. Match a single dot
)$ End of string
Regex demo
let pattern = /^[0-9]+(?:(?:\.[0-9]{1,2})?[km]?|\.)$/;
[
"400k",
"400.2k",
"4m",
"500000",
"500.",
"300.k",
"4.2.k",
".3k",
"4...k",
].forEach(s => console.log(s + " --> " + pattern.test(s)));
Another option is to only match the dot when not directly followed by k or m
^[0-9]+(?:\.(?![km]))?\d*[km]?$
Regex
You can try:
^\d+\.?(?:\d+)?[KkMm]?(?<!\.[KkMm])$
Explanation of the above regex:
^, $ - Matches start and end of the line respectively.
\d+ - Matches digits 1 or more times.
\.? - Represents 0 or 1 occurrence of ..
[KkMm]? - Matches optional characters from the mentioned character class.
(?<!\.[KkMm]) - Represents a negative look-behind not matching a a character after ..
You can find the demo of the above regex in here.
const regex = /^\d+\.?(?:\d+)?[KkMm]?(?<!\.[KkMm])$/gm;
const str = `400K
4.2.K
4.3K
3.2M
300000
4....K
4K
500.
300.K`;
let m;
while ((m = regex.exec(str)) !== null) {
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`${match}`);
});
}
2nd efficient solution using alternation:
You can probably try this regex for more efficient implementation
^\d+(?:\.$|\.\d+)?[KkMm]?$
Explanation of the above regex:
^, $ - Matches start and end of the line respectively.
\d+ - Matches digits 1 or more times.
(?:\.$|\.\d+)? - Represents a non-capturing group; matching either numbers followed by only . or decimal numbers.
[KkMm]? - Matches one of the mentioned characters zero or 1 time.
You can find the demo of the above regex in here.
const regex = /^\d+(?:\.$|\.\d+)?[KkMm]?$/gm;
const str = `400K
4.2.K
4.3K
3.2M
300000
4....K
4K
500.
300.K`;
let m;
while ((m = regex.exec(str)) !== null) {
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`${match}`);
});
}
I want to match certain parts of a URL that has the following form:
http://example.com/somepath/this-is-composed-of-hypens-3144/someotherpath
More precisely, I want to match only the part that is composed of all hypens and ends in numbers. So, I want to extract the part this-is-composed-of-hypens-3144 in the above URL. I have something like this:
const re = /[a-z]*-[a-z]*-[0-9]*/gis;
const match = re.exec(url);
return (match && match.length) ? match[0] : null;
However, this works only if there are 2 hypens, however, the number of hypens in my case can be arbitrary. How can I make my regex work for arbitrary number of hypens?
You may use
/\/([a-z]+(?:-[a-z]+)*-[0-9]+)(?:\/|$)/i
See the regex demo
Details
\/ - a / char
([a-z]+(?:-[a-z]*)*-[0-9]+) - Capturing group 1:
[a-z]+ - 1+ ASCII letters
(?:-[a-z]+)* - 0+ occurrences of - followed with 1+ ASCII letters
(?:\/|$) - either / or end of string.
If there can be any word chars, not just ASCII letters, you may replace each [a-z] with \w.
var s = "http://example.com/somepath/this-is-composed-of-hypens-3144/someotherpath";
var m = s.match(/\/([a-z]+(?:-[a-z]+)*-[0-9]+)(?:\/|$)/i);
if (m) {
console.log(m[1]);
}
I'm trying to find a regular expression that will match the base string without the optional trailing number (_123). e.g.:
lorem_ipsum_test1_123 -> capture lorem_ipsum_test1
lorem_ipsum_test2 -> capture lorem_ipsum_test2
I tried using the following expression, but it would only work when there is a trailing _number.
/(.+)(?>_[0-9]+)/
/(.+)(?>_[0-9]+)?/
Similarly, adding the ? (zero or more) quantifier only worked when there is no trailing _number, otherwise, the trailing _number would just be part of the first capture.
Any suggestions?
You may use the following expression:
^(?:[^_]+_)+(?!\d+$)[^_]+
^ Anchor beginning of string.
(?:[^_]+_)+ Repeated non capturing group. Negated character set for anything other than a _, followed by a _.
(?!\d+$) Negative lookahead for digits at the end of the string.
[^_]+ Negated character set for anything other than a _.
Regex demo here.
Please note that the \n in the character sets in the Regex demo are only for demonstration purposes, and should by all means be removed when using as a pattern in Javascript.
Javascript demo:
var myString = "lorem_ipsum_test1_123";
var myRegexp = /^(?:[^_]+_)+(?!\d+$)[^_]+/g;
var match = myRegexp.exec(myString);
console.log(match[0]);
var myString = "lorem_ipsum_test2"
var myRegexp = /^(?:[^_]+_)+(?!\d+$)[^_]+/g;
var match = myRegexp.exec(myString);
console.log(match[0]);
You might match any character and use a negative lookahead that asserts that what follows is not an underscore, one or more digits and the end of the string:
^(?:(?!_\d+$).)*
Explanation
^ Assert start of the string
(?: Non capturing group
(?! Negative lookahead to assert what is on the right side is not
_\d+$Match an underscore, one or more digits and assert end of the string
.) Match any character and close negative lookahead
)* Close non capturing group and repeat zero or more times
Regex demo
const strings = [
"lorem_ipsum_test1_123",
"lorem_ipsum_test2"
];
let pattern = /^(?:(?!_\d+$).)*/;
strings.forEach((s) => {
console.log(s + " ==> " + s.match(pattern)[0]);
});
You are asking for
/^(.*?)(?:_\d+)?$/
See the regex demo. The point here is that the first dot pattern must be non-greedy and the _\d+ should be wrapped with an optional non-capturing group and the whole pattern (especially the end) must be enclosed with anchors.
Details
^ - start of string
(.*?) - Capturing group 1: any zero or more chars other than line break chars, as few as possible due to the non-greedy ("lazy") quantifier *?
(?:_\d+)? - an optional non-capturing group matching 1 or 0 occurrences of _ and then 1+ digits
$ - end of string.
However, it seems easier to use a mere replacing approach,
s = s.replace(/_\d+$/, '')
If the string ends with _ and 1+ digits, the substring will get removed, else, the string will not change.
See this regex demo.
Try to check if the string contains the trailing number. If it does you get only the other part. Otherwise you get the whole string.
var str = "lorem_ipsum_test1_123"
if(/_[0-9]+$/.test(str)) {
console.log(str.match(/(.+)(?=_[0-9]+)/g))
} else {
console.log(str)
}
Or, a lot more concise:
str = str.replace(/_[0-9]+$/g, "")
Is there any simple way to check if first and last character of a string are the same or not, only with regex?
I know you can check with charAt
var firstChar = str.charAt(0);
var lastChar = str.charAt(length-1);
console.log(firstChar===lastChar):
I'm not asking for this : Regular Expression to match first and last character
You can use regex with capturing group and its backreference to assert both starting and ending characters are same by capturing the first caharacter. To test the regex match use RegExp#test method.
var regex = /^(.).*\1$/;
console.log(
regex.test('abcdsa')
)
console.log(
regex.test('abcdsaasaw')
)
Regex explanation here :
^ asserts position at start of the string
1st Capturing Group (.)
.* matches any character (except newline) - between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\1 matches the same text as most recently matched by the 1st capturing group
$ asserts position at the end of the string
The . doesn't include newline character, in order include newline update the regex.
var regex = /^([\s\S])[\s\S]*\1$/;
console.log(
regex.test(`abcd
sa`)
)
console.log(
regex.test(`ab
c
dsaasaw`)
)
Refer : How to use JavaScript regex over multiple lines?
Regex explanation here :
[.....] - Match a single character present
\s - matches any whitespace character (equal to [\r\n\t\f\v ])
\S - matches any non-whitespace character (equal to [^\r\n\t\f ])
finally [\s\S] is matches any character.
You can try it
const rg = /^([\w\W]+)[\w\W]*\1$/;
console.log(
rg.test(`abcda`)
)
console.log(
rg.test(`aebcdae`)
)
console.log(
rg.test(`aebcdac`)
)
var rg = /^([a|b])([a|b]+)\1$|^[a|b]$/;
console.log(rg.test('aabbaa'))
console.log(rg.test('a'))
console.log(rg.test('b'))
console.log(rg.test('bab'))
console.log(rg.test('baba'))
This will make sure that characters are none other than a and b which have the same start and end.
It will also match single characters because they too start and end with same character.