using regular expressions in groovy - regex

I don't understand how I should use regular expressions in groovy despite it having several operators to work with it.
import java.util.regex.*
def line = "Line with 1 digits"
Pattern p = Pattern.compile("\\d+")
Matcher m = p.matcher(line)
if (m.find()) { // true
println "found digit"
} else {
println "not found digit"
}
if (line ==~ /\\d+/) { // false
println "found"
} else {
println "not found"
}
if (line =~ /\\d+/) { // false
println "found"
} else {
println "not found"
}
In my example in java code it found that there is a digit in the string successfully. However in groovy it was not able to do it.
What is wrong?

See this slashy string reference:
Slashy strings are particularly useful for defining regular expressions and patterns, as there is no need to escape backslashes.
You need to use a single backslash with \d in /\d+/ Groovy slashy strings defining a regex.
if (line =~ /\d+/) { // false
println "found"
} else {
println "not found"
}
The line =~ /\d+/ checks if a line contains one or more digits.
The line2 ==~ /\d+/ checks if the whole string consists of only digits.
See IDEONE demo.
Also, see some more information about using regex in Groovy at regular-expressions.info.

You can use find
if (line.find(/\d+/)) {
println "found"
} else {
println "not found"
}

Just as an addition if you need a Boolean, like
def myBool = line.find(/\d+/)
this returns null, if it cannot find it - and the number it matches otherwise.
Same with line =~ /\d+/ that returns a java.util.regex.Matcher.
So to get a Boolean directly you can for example extend the Regex and use matches:
def myBool = line..matches(/.*\d+.*/))

Related

Find one or more word in string using Regex in Kotlin

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.

How to check is Jenkins pram contains a character

I am trying to check if my Jenkins parameter contains a hostname.
But when I use Regular Expressions to see if it contains the name it doesn't check.
I would guess I have an error in the way I am checking or how I have it wrapped in brackets.
Below is a sample of what I am working with
stage('Release 1') {
when {
expression { params.SECRET_NAME != "" && params.STAGING_ENV != ("*some.host.name*") }
}
steps {
echo "Release 1"
}
}
stage('Release 2') {
when {
expression {params.STAGING_ENV == ("*some.host.name*") && params.SECRET_NAME == ("*+*") }
}
steps {
echo "Release 2"
}
}
}
I want it to skip the stage in my Jenkins pipeline if it does not meet the conditions
Ok, you need multiple changes here, from inside out:
Replace the * with .*. Simply put, in regex * denotes the same (set) of characters any number of times (abc* matches abccccc), whereas .* denotes any character any number of times (abc.* matches abccccc, abcdefg, abcadkhsdalksd, etc.).
Remove the double quotes " surrounding the regex patterns; lest you want them to be interpreted as string literals.
Wrap the regex patterns within delimiters, usually / to define the string boundary.
The brackets () themselves are optional here.
To match regular expressions, replace the equal operator == with the match operator ==~ (strict), which returns a boolean.
There is no "NOT match" operator in Groovy. To invert the match, you need to invert the result of the entire expression.
If the + in *+*should be a literal, then you must escape it as *\+*.
Stitching these together, your pipeline should look like:
stage('Release 1') {
when {
expression {
params.SECRET_NAME != "" && !(params.STAGING_ENV ==~ /.*some.host.name.*/)
}
}
steps {
echo "Release 1"
}
}
stage('Release 2') {
when {
expression {
params.STAGING_ENV ==~ /.*some.host.name.*/ && params.SECRET_NAME ==~ /.*\+.*/
}
}
steps {
echo "Release 2"
}
}
Further reading:
http://docs.groovy-lang.org/latest/html/documentation/core-operators.html
http://web.mit.edu/hackl/www/lab/turkshop/slides/regex-cheatsheet.pdf

Groovy not matching left braces in regex

Groovy 2.4 here. I have a list of characters I'd like to match, specifically:
`;[]&<>?:()|
My best attempt:
import java.util.regex.Matcher;
Matcher matcher
String illNameChars = /[`\/;\[\]&<>?:\()|-]+/
String input = "Bupo;dupo"
if(input) {
matcher = input =~ illNameChars
if(matcher.matches()) {
println "Illegal character detected!"
}
}
This works for the first character (the backtick "`") and the second character (";"), but not the third character ("[")...any ideas as to why?
You are double escaping the braces:
Try:
import java.util.regex.Matcher;
String input = "["
Matcher matcher = input =~ /[`\/;\[\]&<>?:\()|-]+/
if(matcher.matches()) {
println "Matched!"
} else {
println "No match!"
}
Notice only one escape for the [ and ] characters. This resulted in a match when I ran it.

Groovy regexes and wildcard permissions

Given the following Groovy:
static void main(String[] args) {
String permission = "[fizz]:[index]"
String regex = "[fizz]:[*]"
if((permission =~ regex).matches()) {
println "We match!"
} else {
println "We don't match!"
}
}
The result is: "We don't match!". How is this possible?!?
You need to escape square brackets and, to match index, you need to use .*, which means "any char, any number of times". Also, groovy's slashy string syntax helps:
String permission = "[fizz]:[index]"
String regex = /\[fizz]:\[.*]/
assert (permission =~ regex).matches()
assert permission ==~ regex
Update: you can use double quote string by escaping square brackets twice:
String regex = "\\[fizz]:\\[.*]"

How to match String with Pattern in Groovy

I am trying to decide whether a simple regular expression matches a string in Groovy. Here's my task in gradle. I tried to match with 2 different ways I found on the net, but neither of them works. It always prints out "NO ERROR FOUND"
task aaa << {
String stdoutStr = "bla bla errors found:\nhehe Aborting now\n hehe"
println stdoutStr
Pattern errorPattern = ~/error/
// if (errorPattern.matcher(stdoutStr).matches()) {
if (stdoutStr.matches(errorPattern)) {
println "ERROR FOUND"
throw new GradleException("Error in propel: " + stdoutStr)
} else {
println "NO ERROR FOUND"
}
}
(?s) ignores line breaks for .* (DOTALL) and the regexp there means a full match. so with ==~ as shortcut it's:
if ("bla bla errors found:\nhehe Aborting now\n hehe" ==~ /(?s).*errors.*/) ...
if (errorPattern.matcher(stdoutStr).matches()) {
The matches() method requires the whole string to match the pattern, if you want to look for matching substrings use find() instead (or just if(errorPattern.matcher(stdoutStr)) since Groovy coerces a Matcher to Boolean by calling find).