El operador =~
permite hacer casamientos parciales.
Retorna un objeto util.regex.Matcherlang/util.regex.Matcherutil/regex/Matcher.html:
generaciondecodigos@nereida:~/src/groovy/strings$ groovysh Groovy Shell (1.6.5, JVM: 1.6.0_0) Type 'help' or '\h' for help. ---------------------------------------------------------------------------------- groovy:000> ("New York, NY 10292" =~ /\d{5}/).class ===> class java.util.regex.Matcher groovy:000> ("New York, NY 10292" =~ /\d{5}/)[0] ===> 10292 groovy:000> ("New York, NY" =~ /\d{5}/)[0] ERROR java.lang.IndexOutOfBoundsException: index is out of range 0..-1 (index = 0) at groovysh_evaluate.run (groovysh_evaluate:2) ...Como se ve, si no hay casamiento se produce un error, ya que el array está vacío. Es por tanto conveniente asegurarse que se ha producido casamiento:
groovy:000> m = ("New York, NY 10292" =~ /\d{5}/) ===> java.util.regex.Matcher[pattern=\d{5} region=0,18 lastmatch=] groovy:000> if (m) { m[0] } ===> 10292 groovy:000> m = ("New York, NY" =~ /\d{5}/) ===> java.util.regex.Matcher[pattern=\d{5} region=0,12 lastmatch=] groovy:000> if (m) { m[0] } ===> null groovy:000> m = ("New York, NY" =~ /\d{5}/) ===> java.util.regex.Matcher[pattern=\d{5} region=0,12 lastmatch=] groovy:000> m.find() ===> falseSi la expresión regular tiene paréntesis de captura en su interior se devuelve un array conteniendo lo que se ha capturado en los paréntesis:
groovy:000> m = "foo car baz" =~ /(.)ar/ ===> java.util.regex.Matcher[pattern=(.)ar region=0,11 lastmatch=] groovy:000> m[0] ===> [car, c] groovy:000> m[0][1] ===> c
Veamos un ejemplo de uso de expresiones regulares en Groovy. el siguiente programa traduce entre temperaturas en escala Celsius y Farenheit:
~/src/groovy/strings$ cat -n c2f.groovy 1 #!/opt/local/bin/groovy 2 def re = '''(?ix) 3 ^ # begin of string 4 \\s* 5 ([-+]?\\d+(?:\\.\\d*)?) # number 6 \\s* 7 ([cf]) # type 8 \\s* 9 $ # end of string 10 '''; 11 12 print "Enter a temperature (i.e. 32F, 100C): "; 13 14 def stdin = new BufferedReader(new InputStreamReader(System.in)) 15 stdin.eachLine{ input -> 16 def m = (input =~ re); 17 18 if (m) { 19 def (num, type) = m[0][1..2] 20 if ((type == 'C') || (type == 'c')) { 21 celsius = num.toDouble() 22 farenheit = (celsius * 9/5)+32 23 } 24 else { 25 farenheit = num.toDouble() 26 celsius = (farenheit -32)*5/9; 27 } 28 printf "%.2f C = %.2f F\n", celsius, farenheit; 29 } // this message to System.err 30 else System.err.println "Expecting a temperature, so don't understand \"$input\"" 31 32 print "Enter a temperature (i.e. 32F, 100C): "; 33 } // end eachLine loop
Ejecución:
~/src/groovy/strings$ groovy c2f Enter a temperature (i.e. 32F, 100C): 32f 0,00 C = 32,00 F Enter a temperature (i.e. 32F, 100C): 100c 100,00 C = 212,00 F Enter a temperature (i.e. 32F, 100C): juan Expecting a temperature, so don't understand "juan" Enter a temperature (i.e. 32F, 100C): ~/src/groovy/strings$La última vez hemos presionado
CTRL-D
(unix) para generar
el final de fichero.
Casiano Rodríguez León