i am new to scala and hate regex :D
cuurently i am debuggig a piece of code
def validateReslutions(reslutions: String): Unit = {
val regex = "(\\d+-\\d+[d,w,m,h,y],?)*"
if (!reslutions.matches(regex)) {
throw new Error("no match")
} else {
print("matched")
}
}
validateReslutions(reslutions = "(20-1w,100-1w)")
}
the problem is it produces no match for this input , so how to correct the regex to match this input
Your (20-1w,100-1w) string contains a pair of parentheses at the start and end, and the rest matches with your (\d+-\d+[d,w,m,h,y],?)* regex. Since String#matches requires a full string match, you get an exception.
Include the parentheses patterns to the regex to avoid the exception:
def validateReslutions(reslutions: String): Unit = {
val regex = """\((\d+-\d+[dwmhy],?)*\)"""
if (!reslutions.matches(regex)) {
throw new Error("no match")
} else {
print("matched")
}
}
validateReslutions(reslutions = "(20-1w,100-1w)")
// => matched
See the Scala demo.
Note the triple quotes used to define the string literal, inside which you can use single backslashes to define literal backslash chars.
Also, mind the absence of commas in the character class, they match literal commas in the text, they do not mean "or" inside character classes.
Related
I use regex validation in my custom textfield listener, to check if password valid
this is my validation code
RegExp regexUpper = RegExp(r'^(?=.*[A-Z])$');
RegExp regexLower = RegExp(r'^(?=.*[a-z])$');
RegExp regexLength = RegExp(r'^.{8,}$');
if (!regexLength.hasMatch(value.toString())) {
return 'Пароль слишком короткий';
}
if (!regexLower.hasMatch(value.toString())) {
print(value);
return 'Пароль должен содержать хотя бы одну маленькую букву';
}
if (!regexUpper.hasMatch(value.toString())) {
return 'Введите хотя бы одну заглавную букву';
}
return null;
regexLength work correctly but other not.
What i did wrong and how i can fix it ?
You should not use lookarounds wrapped with anchors.
You can fix the issues with
RegExp regexUpper = RegExp(r'[A-Z]');
RegExp regexLower = RegExp(r'[a-z]');
RegExp regexLength = RegExp(r'^.{8,}$');
Look: ^(?=.*[A-Z])$ asserts the current position at the start of string (^), then checks if there is an uppercase ASCII letter ([A-Z]) anywhere after zero or more chars other than line break chars (as many as possible, with .*), and then requires the end of string ($) (right at the start of string). This is an example of a pattern that never matches any string.
I have a scenario where i want to extract some substring based on following condition.
search for any pattern myvalue=123& , extract myvalue=123
If the "myvalue" present at end of the line without "&", extract myvalue=123
for ex:
The string is abcdmyvalue=123&xyz => the it should return myvalue=123
The string is abcdmyvalue=123 => the it should return myvalue=123
for first scenario it is working for me with following regex - myvalue=(.?(?=[&,""]))
I am looking for how to modify this regex to include my second scenario as well. I am using https://regex101.com/ to test this.
Thanks in Advace!
Some notes about the pattern that you tried
if you want to only match, you can omit the capture group
e* matches 0+ times an e char
the part .*?(?=[&,""]) matches as least chars until it can assert eiter & , or " to the right, so the positive lookahead expects a single char to the right to be present
You could shorten the pattern to a match only, using a negated character class that matches 0+ times any character except a whitespace char or &
myvalue=[^&\s]*
Regex demo
function regex(data) {
var test = data.match(/=(.*)&/);
if (test === null) {
return data.split('=')[1]
} else {
return test[1]
}
}
console.log(regex('abcdmyvalue=123&3e')); //123
console.log(regex('abcdmyvalue=123')); //123
here is your working code if there is no & at end of string it will have null and will go else block there we can simply split the string and get the value, If & is present at the end of string then regex will simply extract the value between = and &
if you want to use existing regex then you can do it like that
var test = data1.match(/=(.*)&|=(.*)/)
const result = test[1] ? test[1] : test[2];
console.log(result);
I'm making a method in Kotlin using Regex that checks if a string contains one or more of certain pronouns (such as "I", "we", "you", etc). E.g. "We are a tech company" should be a match, "Web is for spiders" should not be a match.
I tried with this code:
fun main() {
val text = "We are testing!"
val regex = "/\b(i|you|we)\b/g".toRegex()
if (regex.containsMatchIn(text.lowercase())) {
println("match")
} else {
println("no match")
}
}
, but it prints "no match".
Kotlin (and Java) regexps are defined with string literals, and not regex literals, i.e. when you add / at the start and /g (or just /) at the end of the pattern, you actually add them to the pattern string.
You can use the following fix:
val text = "We are testing!"
val regex = """(?i)\b(i|you|we)\b""".toRegex()
if (regex.containsMatchIn(text)) {
println("match")
} else {
println("no match")
}
The """(?i)\b(i|you|we)\b""" is equal to "(?i)\\b(i|you|we)\\b", the former treats backslashes as literal chars.
Note you do not need to use .lowercase(), the (?i) case insensitive modifier will make matching case insensitive.
See the online Kotlin demo.
I'm trying to implement the escape character functionality in a macro generator I'm writing in Dart. For example, I would like the program to grab all the occurrences of '¶m' in my string and replace it with 'John', unless the '&' character is preceded with the escape character '\'. Example: "My name is ¶m and my parameter is called \¶m." -> "My name is John and my parameter is called ¶m". What would be the regular expression to catch all the substrings that contain the '&', then my parameter's name, and without the preceding '\'?
It's possible to match that, even avoiding escapes of backslashes, as:
var re = RegExp(r"(?<!(?:^|[^\\])(?:\\{2})*\\)&\w+");
This uses negative lookbehind to find a & followed by word-characters, and not preceded by an odd number of backslashes.
More likely, you want to also recognize double-backslashes and convert them to single-backslashes. That's actually easier if you try to find all matches, because then you know all preceding double-backslashes are part of an earlier match:
var re = RegExp(r"\\\\|(?<!\\)&\w+");
This, when used as re.allMatches will find all occurrences of \\ and &word where the latter is not preceded by an odd number of backslashes.
var _re = RegExp(r"\\\\|(?<!\\)&(\w+)");
String template(String input, Map<String, String> values) {
return input.replaceAllMapped(_re, (m) {
var match = m[0]!;
if (match == r"\\") return r"\";
var replacement = values[m[1]!];
if (replacement != null) return replacement;
// do nothing for undefined words.
return match;
});
}
(You might also want to allow something like &{foo} if parameters can occur next to other characters, like &{amount)USD).
To keep the character before ¶m when it matches a non-backslash character you need to use so called capturing groups. These are are subexpressions of a regular expression inside parentheses. To use capturing groups in Dard you need to use the method replaceAllMapped. We also have the case when the template starts with ¶m and in this case we match at the beginning of the string instead.
Try this:
void main() {
final template = 'My name is ¶m and my parameter is called \\¶m.';
final populatedTemplate = template.replaceAllMapped(RegExp(r'(^|[^\\])¶m\b'), (match) {
return '${match.group(1)}John';
});
final result = populatedTemplate.replaceAll(RegExp(r'\\¶m\b'), 'John');
print(result);
}
Groovy here : I need to scan a string for a substring of the form:
${token}:<someValue>]
That is:
A user-define (dynamic) token string (could be anything at runtime); then
A colon (:); then
Anything (<someValue>); then finally
A right squre bracket (])
So basically something like:
def String fetchTokenValue(String toScan, String token) {
if(toScan.matches(".*${token}:.*]")) {
String everythingBetweenColonAndRBracket = ???
return everythingBetweenColonAndRBracket
} else {
return 'NO_DICE'
}
}
Such that the output would be as follows:
fetchTokenValue('swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko', 'blah') => 'fizzbuzz'
fetchTokenValue('swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko', 'boo') => 'NO_DICE'
I'm struggling with the regex as well as how to, if a match is made, extract all the text between the colon and the right square bracket. We can assume there will only ever be one match, or simply operate on the first match that is found (if it exists).
Any ideas where I'm going awry?
You may use [^\]]* subpattern (a negated character class [^...] that matches any chars other than those defined inside it) to match zero or more chars other than ] and use a capturing group to capture that text and only return Group 1 contents. Also, it is a good idea to automatically escape the input token so as to avoid illegal pattern syntax issues:
import java.util.regex.*;
def String fetchTokenValue(String toScan, String token) {
def matcher = ( toScan =~ /.*${Pattern.quote(token)}:([^\]]*)].*/ )
if(matcher.matches()) {
return matcher.group(1)
} else {
return 'NO_DICE'
}
}
println fetchTokenValue('swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko', 'blah')
See the online Groovy demo
You could use this regex which grabs anything up to a ] into a group
def String fetchTokenValue(String toScan, String token) {
def match = toScan =~ /.+${token}:([^\]]+)/
if(match) { match[0][1] } else { 'NO_DICE' }
}
def str = 'swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko'
assert fetchTokenValue(str, 'blah') == 'fizzbuzz'
assert fetchTokenValue(str, 'boo') == 'NO_DICE'