Regex match between parenthesis and other characters - regex

I am trying to match the numbers between this string, I don't need to match anything after the number.
(14,240 Reviews)
Trying everything I know and not have any luck.
I tried this but I think its incorrect.
((\d){1,3})+([,][\d]{3})*([.](\d)*)?
Desired Results is 14,240

/(\d{1,3}(,\d{3})*)\sReviews?/
It will find any number inside the parathesis.
const pattern = /(\d{1,3}(,\d{3})*)\sReviews?/;
const testStrings = [
"(14,240 Review)",
"(1 Review)",
"(10 Reviews)",
"(100 Reviews)",
"(1,000 Reviews)",
"(10,000 Reviews)",
"(100,000 Reviews)",
"(1,000,000 Reviews)",
"(10,000,000 Reviews)",
"(100,000,000 Reviews)",
"(1,000,000,000 Reviews)"
];
testStrings.forEach((text) => {
const match = text.match(pattern);
const number = match ? match[1] : '';
console.log(number); // prints the number extracted from each test string
})

console.log('(14,240 Reviews)'.match(/(\d+)/g))

Related

Filter list using dynamic whole word matching regex in dart

I'm filtering list like this but i think there should be better approach to filter list inside where bloc it is not allowing me to declare variable. is there any other way to achieve the same
var cc = contactsAll
.where(
(i) =>
regularExpression(i.displayName, 'dev') ||
regularExpression(i.displayName, 'soft') ||
regularExpression(i.displayName, 'angular') ||
regularExpression(i.displayName, 'java')
)
.toList();
my expression filter function
bool regularExpression(String stringg, String search) {
RegExp exp = new RegExp(
"\\b" + search + "\\b",
caseSensitive: false,
);
return exp.hasMatch(stringg);
}
Thanks in advance
You may build the pattern dynamically:
var keys = ['dev', 'soft', 'angular', 'java'];
var regex = new RegExp("\\b(?:${keys.join('|')})\\b", caseSensitive: false);
var contactsAll = ['No match', 'I like java', 'I like javascript'];
var cc = contactsAll.where( (i) => regex.hasMatch(i) ).toList();
print(cc); // => [I like java]
The regex will look like \b(?:dev|soft|angular|java)\b and will match any of the keywords inside the non-capturing group as a whole word due to the \b word boundaries. See the regex demo.
If the keys can contain special characters, but you still need a whole word search, you need to escape all special characters and use either unambiguous boundaries
var regex = new RegExp("(?:^|\\W)(?:${keys.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]{}]'), r'\\$&')).join('|')})(?!\\w)", caseSensitive: false);
This results in a (?:^|\W)(?:dev|soft|angular|java)(?!\w) pattern (see demo) where (?:^|\W) matches start of string or a non-word char and (?!\w) requires the absense of a word char immediately to the right of the current location.
The .map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]{}]'), r'\\$&')) part escapes the literal part for use within regex.
Or whitespace boundaries:
var regex = new RegExp("(?:^|\\s)(?:${keys.map((val) => val.replaceAll(new RegExp(r'[-\/\\^$*+?.()|[\]{}]'), r'\\$&')).join('|')})(?!\\S)", caseSensitive: false);
This results in a (?:^|\s)(?:dev|soft|angular|java)(?!\S) pattern where (?:^|\s) matches start of string or a whitespace char and (?!\S) requires the absense of a non-whitespace char immediately to the right of the current location.
See the regex demo.
Without creating a function, you can use the contains method on your displayName like this :
var cc = contactsAll
.where((i) =>
i.displayName.contains(RegExp('\\bdev\\b')) ||
i.displayName.contains(RegExp('\\bsoft\\b')) ||
i.displayName.contains(RegExp('\\bangular\\b')) ||
i.displayName.contains(RegExp('\\bjava\\b')),)
.toList();

How to make regexp for multiple condition?

I have regexp code like below (I'm using VerbalExpression dart plugin ), My purpose is to check that a string starts with "36", followed by "01", "02", or "03". After that can be anything as long as the whole string is 16 characters long.
var regex = VerbalExpression()
..startOfLine()
..then("36")
..then("01")
..or("02")
..anythingBut(" ")
..endOfLine();
String nik1 = "3601999999999999";
String nik2 = "3602999999999999";
String nik3 = "3603999999999999";
print('result : ${regex.hasMatch(nik1)}');
print('Hasil : ${regex.hasMatch(nik2)}');
print('Hasil : ${regex.hasMatch(nik3)}');
my code only true for nik1 and nik2, however i want true for nik3, I noticed that i can't put or() after or() for multiple check, it just give me all false result, how do i achieve that?
I'm not familiar with VerbalExpression, but a RegExp that does this is straightforward enough.
const pattern = r'^36(01|02|03)\S{12}$';
void main() {
final regex = RegExp(pattern);
print(regex.hasMatch('3601999999999999')); // true
print(regex.hasMatch('3602999999999999')); // true
print(regex.hasMatch('3603999999999999')); // true
print(regex.hasMatch('360199999999999')); // false
print(regex.hasMatch('3600999999999999')); // false
print(regex.hasMatch('36019999999999999')); // false
}
Pattern explanation:
The r prefix means dart will interpret it as a raw string ("$" and "\" are not treated as special).
The ^ and $ represent the beginning and end of the string, so it will only match the whole string and cannot find matches from just part of the string.
(01|02|03) "01" or "02" or "03". | means OR. Wrapping it in parentheses lets it know where to stop the OR.
\S matches any non-whitespace character.
{12} means the previous thing must be repeated 12 times, so \S{12} means any 12 non-whitespace characters.

Kotlin .split() with multiple regex

Input: """aaaabb\\\\\cc"""
Pattern: ["""aaa""", """\\""", """\"""]
Output: [aaa, abb, \\, \\, \, cc]
How can I split Input to Output using patterns in Pattern in Kotlin?
I found that Regex("(?<=cha)|(?=cha)") helps patterns to remain after spliting, so I tried to use looping, but some of the patterns like '\' and '[' require escape backslash, so I'm not able to use loop for spliting.
EDIT:
val temp = mutableListOf<String>()
for (e in Input.split(Regex("(?<=\\)|(?=\\)"))) temp.add(e)
This is what I've been doing, but this does not work for multiple regex, and this add extra "" at the end of temp if Input ends with "\"
You may use the function I wrote for some previous question that splits by a pattern keeping all matched and non-matched substrings:
private fun splitKeepDelims(s: String, rx: Regex, keep_empty: Boolean = true) : MutableList<String> {
var res = mutableListOf<String>() // Declare the mutable list var
var start = 0 // Define var for substring start pos
rx.findAll(s).forEach { // Looking for matches
val substr_before = s.substring(start, it.range.first()) // // Substring before match start
if (substr_before.length > 0 || keep_empty) {
res.add(substr_before) // Adding substring before match start
}
res.add(it.value) // Adding match
start = it.range.last()+1 // Updating start pos of next substring before match
}
if ( start != s.length ) res.add(s.substring(start)) // Adding text after last match if any
return res
}
You just need a dynamic pattern from yoyur Pattern list items by joining them with a |, an alternation operator while remembering to escape all the items:
val Pattern = listOf("aaa", """\\""", "\\") // Define the list of literal patterns
val rx = Pattern.map{Regex.escape(it)}.joinToString("|").toRegex() // Build a pattern, \Qaaa\E|\Q\\\E|\Q\\E
val text = """aaaabb\\\\\cc"""
println(splitKeepDelims(text, rx, false))
// => [aaa, abb, \\, \\, \, cc]
See the Kotlin demo
Note that between \Q and \E, all chars in the pattern are considered literal chars, not special regex metacharacters.

Split with a multicharacter regex pattern and keep delimiters

I have next string and regex for splitting it:
val str = "this is #[loc] sparta"
val regex = "((?<=( #\\[\\w{3,100}\\] ))|(?=( #\\[\\w{3,100}\\] )))"
print(str.split(Regex(regex)))
//print - [this is, #[loc] , sparta]
Works fine. But in develop I did not realize when in #[***] block must be a not only text (\w) - he have and "-" and numbers (UUID), and my correct blocks is -
val str = "this is #[loc_75acca83-a39b-4df1-8c3c-b690df00db62]"
and in this case regex don't work.
How to change this part - "\w{3,100}" for new requirements?
I try change to any - "\.{3,100}" - not work
To fix your issue, you may replace your regex with
val regex = """((?<=( #\[[^\]\[]{3,100}] ))|(?=( #\[[^\]\[]{3,100}] )))"""
The \w can be replaced with [^\]\[] that matches any char but [ and ].
Note the use of a raw string literal, """...""", that allows the use of a single backslash as a regex escape.
See the Kotlin online demo.
Alternatively, you may use the following method to split and keep delimiters:
private fun splitKeepDelims(s: String, rx: Regex, keep_empty: Boolean = true) : MutableList<String> {
var res = mutableListOf<String>() // Declare the mutable list var
var start = 0 // Define var for substring start pos
rx.findAll(s).forEach { // Looking for matches
val substr_before = s.substring(start, it.range.first()) // // Substring before match start
if (substr_before.length > 0 || keep_empty) {
res.add(substr_before) // Adding substring before match start
}
res.add(it.value) // Adding match
start = it.range.last()+1 // Updating start pos of next substring before match
}
if ( start != s.length ) res.add(s.substring(start)) // Adding text after last match if any
return res
}
Then, just use it like
val str = "this is #[loc_75acca83-a39b-4df1-8c3c-b690df00db62] sparta"
val regex = """#\[[\]\[]+]""".toRegex()
print(splitKeepDelims(str, regex))
// => [this is , #[loc_75acca83-a39b-4df1-8c3c-b690df00db62], sparta]
See the Kotlin demo.
The \[[^\]\[]+] pattern matches
\[ - a [ char
[^\]\[]+ - 1+ chars other than [ and ]
] - a ] char.

Challenging regular expression

There is a string in the following format:
It can start with any number of strings enclosed by double braces, possibly with white space between them (whitespace may or may not occur).
It may also contain strings enclosed by double-braces in the middle.
I am looking for a regular expression that can separate the start from the rest.
For example, given the following string:
{{a}}{{b}} {{c}} def{{g}}hij
The two parts are:
{{a}}{{b}} {{c}}
def{{g}}hij
I tried this:
/^({{.*}})(.*)$/
But, it captured also the g in the middle:
{{a}}{{b}} {{c}} def{{g}}
hij
I tried this:
/^({{.*?}})(.*)$/
But, it captured only the first a:
{{a}}
{{b}} {{c}} def{{g}}hij
This keeps matching {{, any non { or } character 1 or more times, }}, possible whitespace zero or more times and stores it in the first group. Rest of the string will be in the 2nd group. If there are no parts surrounded by {{ and }} the first group will be empty. This was in JavaScript.
var str = "{{a}}{{b}} {{c}} def{{g}}hij";
str.match(/^\s*((?:\{\{[^{}]+\}\}\s*)*)(.*)/)
// [whole match, group 1, group 2]
// ["{{a}}{{b}} {{c}} def{{g}}hij", "{{a}}{{b}} {{c}} ", "def{{g}}hij"]
How about using preg_split:
$str = '{{a}}{{b}} {{c}} def{{g}}hij';
$list = preg_split('/(\s[^{].+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($list);
output:
Array
(
[0] => {{a}}{{b}} {{c}}
[1] => def{{g}}hij
)
I think I got it:
var string = "{{a}}{{b}} {{c}} def{{g}}hij";
console.log(string.match(/((\{\{\w+\}\})\s*)+/g));
// Output: [ '{{a}}{{b}} {{c}} ', '{{g}}' ]
Explanation:
( starts a group.
( another;
\{\{\w+\}\} looks for {{A-Za-z_0-9}}
) closes second group.
\s* Counts whitespace if it's there.
)+ closes the first group and looks for oits one or more occurrences.
When it gets any not-{{something}} type data, it stops.
P.S. -> Complex RegEx takes CPU speed.
You can use this:
(java)
string[] result = yourstr.split("\\s+(?!{)");
(php)
$result = preg_split('/\s+(?!{)/', '{{a}}{{b}} {{c}} def{{g}}hij');
print_r($result);
I donĀ“t know exactly why are you want to split, but in case that the string contains always a def inside, and you want to separate the string from there in two halves, then, you can try something like:
string text = "{{a}}{{b}} {{c}} def{{g}}hij";
Regex r = new Regex("def");
string[] split = new string[2];
int index = r.Match(text).Index;
split[0] = string.Join("", text.Take(index).Select(x => x.ToString()).ToArray<string>());
split[1] = string.Join("", text.Skip(index).Take(text.Length - index).Select(x => x.ToString()).ToArray<string>());
// Output: [ '{{a}}{{b}} {{c}} ', 'def{{g}}hij' ]