Los métodos find y findAll

De nuevo tomado del blog de Ted Naleid Groovy, Grails and OS X tips and tricks:

Groovy 1.6.1 released with new find and findAll regexp methods on String

Groovy 1.6.1 was released today, and it includes a patch I submitted a few weeks ago to make working with regular expressions much more groovy. Thanks to everyone that voted for the patch in the Groovy JIRA

The main functionality is the addition of a variety of find and findAll regular expression aware methods that have been added to string.

If all you need is to scan a string for the portion that matches a regular expression, use find:

generaciondecodigos@nereida:~/src/groovy/files$ groovysh
Groovy Shell (1.6.5, JVM: 1.6.0_0)
Type 'help' or '\h' for help.
--------------------------------------------------------------------------
groovy:000> 'Total Amount: $32.99'.find(/(\d+).(\d{2})/)
===> 32.99

If you need to get access to the capture groups of the regular expression, you can specify a closure that any matched item will be passed to. You then have a chance to manipulate the return value:

generaciondecodigos@nereida:~/src/groovy/strings$ cat -n findNaleid.groovy
     1  #!/usr/bin/env groovy
     2  def roundedAmount(value) {
     3
     4      value.find(/(\d+).(\d{2})/) { fullMatch, dollars, cents ->
     5          return dollars.toInteger() + (cents.toInteger() > 50 ? 1 : 0)
     6      }
     7  }
     8
     9  if (args.length > 0) {
    10    println roundedAmount(args[0])
    11  }
    12  else {
    13    println "Provide one phrase with a number with 2 decimal digits ('like 32.23')"
    14  }
generaciondecodigos@nereida:~/src/groovy/strings$ ./findNaleid.groovy 'Me costó 43.25$'
43
generaciondecodigos@nereida:~/src/groovy/strings$ ./findNaleid.groovy 'I paid $44.28 for it'
44
generaciondecodigos@nereida:~/src/groovy/strings$ ./findNaleid.groovy 'Total Amount: $32.99'
33

If you’re expecting more than one match in a string, you can use the new findAll method to grab the values:

generaciondecodigos@nereida:~/src/groovy/strings$ cat -n findAllNaleid.groovy
     1  #!/usr/bin/env groovy
     2
     3  if (args.length > 1) {
     4    regexp = ~args[0]
     5    string = args[1]
     6
     7    println string.findAll(regexp)
     8  }
     9  else {
    10    println "Provide one regexp and one string"
    11  }
generaciondecodigos@nereida:~/src/groovy/strings$ ./findAllNaleid.groovy '(\d+)' '12, 13, 14 and 15'
[12, 13, 14, 15]
generaciondecodigos@nereida:~/src/groovy/strings$ ./findAllNaleid.groovy '(\w+) Fine' "The stooges are: Moe Fine, Howard Fine, and Larry Fine"
[Moe Fine, Howard Fine, Larry Fine]

Again, if you want to access the capture groups, just add a closure:

def string = "The stooges are: Moe Fine, Howard Fine, and Larry Fine"
def firstNames = string.findAll(/(\w+) Fine/) { match, firstName -> firstName }
 
assert firstNames == ["Moe", "Howard", "Larry"]

All of the methods are “safe” in that they won’t blow up if a match for the regular expression isn’t found, they’ll just return null. This means that they can also be easily used for groovy truth:

def withDigits = "There are 4 items"
 
if (withDigits.find(/\d+/)) {
   assert true
} else {
   assert false 
}

In addition to taking a regular expression string, there is also a variant of each method that takes a precompiled Pattern object. If you are iterating through a ton of strings (such as lines in a file) this version could be useful if you want to avoid recompiling the regex into a pattern every time:

def pattern = ~/.ow/
def owWords = "how now blue cow".findAll(pattern)
assert owWords == ["how", "now", "cow"]

There are additional examples on how to use each of these methods in the groovy documentation for each method:

Thanks to the groovy committers for their suggestions and quick application of the patch (now they just need to apply my other pending patch to remember the font and window size of the groovy console :)

Thanks to the groovy committers for their suggestions and quick application of the patch (now they just need to apply my other pending patch to remember the font and window size of the groovy console :)



Subsecciones
Casiano Rodríguez León
2010-04-30