Thursday, 31 August 2017

groovy - Regex capture for multiple occurrences and place them in groups




I have the following line where the string "winline" may occur 1 or more times (or none) and I do not know in advance how many times it would appear in the line.



Is there a way I can capture all 'winline' that occurs in this text? I am using Groovy and tried just matching the winline and it does capture all but each is stated as group 1. I want to be able to capture them group by group.



Example using this regex on following line: winline\":([0-9]+)



def matcher
def winningSym = /winline\":([0-9]+)/


if((matcher = line =~ winningSym)){
println matcher[0][1] // get 5 which is right
println matcher[1][1] // expect 4 but get IndexOutOfBounds Exception
}


Line:




{"Id":1,"winline":5,"Winnings":50000, some random text, "winline":4,

more random text, "winline":7, more stuff}



Answer



You may slightly modify the regex to use a positive lookbehind and use a simpler code:



def winningSym = /(?<=winline":)[0-9]+/
String s = """{"Id":1,"winline":5,"Winnings":50000, some random text, "winline":4, more random text, "winline":7, more stuff}"""
def res = s.findAll(winningSym)
println(res)



See the Groovy demo, output: [5, 4, 7].



To use your regex and collect Group 1 values use .collect on the matcher (as Matcher supports the iterator() method):



def winningSym = /winline":([0-9]+)/
String line = """{"Id":1,"winline":5,"Winnings":50000, some random text, "winline":4, more random text, "winline":7, more stuff}"""
def res = (line =~ winningSym).collect { it[1] }



See another Groovy demo. Here, it[1] will access the contents inside capturing group 1 and .collect will iterate through all matches.


No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...