Tomado de Groovy: Don’t Fear the RegExp por Ted Naleid
In Groovy, the String class has been enhanced with a few “replace*” methods that allow you to leverage regular expressions. These methods originally come from the Matcher class, but attaching them directly to String puts them right at your fingertips.
replaceFirst
will replace the first substring matched by a
regular expression within the specified String:
~/Lgroovy/strings$ cat -n ReplaceSimple.groovy 1 a = "Hello" 2 b = a.replaceFirst(/$/," world!") 3 println a 4 println b ~/Lgroovy/strings$ groovy ReplaceSimple.groovy Hello Hello world!Nótese que la presencia de
$
en la cadena de reeemplazo altera
la sustitución literal:
groovy:000> a = "Hello" ===> Hello groovy:000> b = a.replaceFirst(/$/," world! ($a)") ===> Hello world! (Hello)
replaceAll
will replace all matching substrings within the specified String:
~/Lgroovy/strings$ cat -n ReplaceAll.groovy 1 text = ''' 2 Poetry (from the Greek "ποίησις", poiesis, a "making") is a form 3 of literary art in which language is used for its aesthetic and 4 evocative qualities in addition to, or in lieu of, its apparent 5 meaning. 6 ''' 7 8 nt = text.replaceAll(/poe/, "Poe") 9 println nt 10 11 nt = text.replaceFirst(/"ποίησις", poiesis/, "POIESIS") 12 println nt ~/Lgroovy/strings$ groovy ReplaceAll.groovy Poetry (from the Greek "ποίησις", poiesis, a "making") is a form of literary art in which language is used for its aesthetic and evocative qualities in addition to, or in lieu of, its apparent meaning. Poetry (from the Greek POIESIS, a "making") is a form of literary art in which language is used for its aesthetic and evocative qualities in addition to, or in lieu of, its apparent meaning.
There is an alternate version of replaceAll
that takes a
closure for the second parameter. This is especially useful in the
situations where you want to manipulate the matched value, or groups
within the match to dynamically determine the replacement text.
For example, if we wanted to be able to turn a dashed phrase (foo-bar
) into a camel case word (fooBar
) we can’t just remove all dash characters, we also need to make the first letter after the dash capitalized (theB
infooBar
).
To do this, we can use a regular expression that captures the first letter after a dash in a group using parenthesis.
~/Lgroovy/strings$ cat -n Hyphen2CamelCase.groovy 1 def dashedToCamelCase(orig) { 2 orig.replaceAll(/-(\w)/) 3 { fullMatch, firstCharacter -> 4 firstCharacter.toUpperCase() 5 } 6 } 7 8 def scanner = new Scanner(System.in) 9 print "Enter dashed string: "; 10 def dashed = scanner.nextLine() 11 def camelcase = dashedToCamelCase(dashed) 12 println camelcase ~/Lgroovy/strings$ groovy Hyphen2CamelCase.groovy Enter dashed string: one-identifier-with-many-hyphens oneIdentifierWithManyHyphens
Using the version of replaceAll
that takes a closure gives
us a chance to manipulate the first character of the word and
capitalize it. This closure is always passed the full matched text
of the regular expression as the first value, and then any groups
as subsequent values.
Here we modify a phone number:
~/Lgroovy/strings$ cat -n Phonenumber.groovy 1 def scanner = new Scanner(System.in) 2 print 'Enter phone number (\\d{0,3})-(\\d{3})-(\\d{6})/): '; 3 def pn = scanner.nextLine() 4 def ac = pn.replaceAll(/(^\s*\d{0,3})[-\s]+(\d{3})[-\s]+(\d{6})\s*$/) { 5 fullMatch, international, areaCode, localNumber -> 6 7 return "$areaCode" 8 } 9 10 println ac ~/Lgroovy/strings$ groovy Phonenumber.groovy Enter phone number (\d{0,3})-(\d{3})-(\d{6})/): 34-922-313131 922 ~/Lgroovy/strings$ groovy Phonenumber.groovy Enter phone number (\d{0,3})-(\d{3})-(\d{6})/): 34 922 313131 922 ~/Lgroovy/strings$ groovy Phonenumber.groovy Enter phone number (\d{0,3})-(\d{3})-(\d{6})/): 34---922-- 313131 922 ~/Lgroovy/strings$ groovy Phonenumber.groovy Enter phone number (\d{0,3})-(\d{3})-(\d{6})/): djfkdjs djfkdjs
He aqui una solución que hace uso de e
al siguiente ejercicio
(véase 'Regex to add space after punctuation sign' en PerlMonks)
Se quiere poner un espacio en blanco después de la aparición de cada coma,
pero se quiere que la sustitución no tenga lugar si la coma esta incrustada entre
dos dígitos. Además se pide que si hay ya un espacio después de la coma,
no se duplique
generaciondecodigos@nereida:~/src/groovy/strings$ cat -n commawhite.groovy 1 def scanner = new Scanner(System.in) 2 print 'Enter string: ' 3 def line = scanner.nextLine() 4 5 def r = line.replaceAll(/(\d[,.]\d)|(,(?!\s))/) { 6 fullMatch, nucnu, stcommanospace -> 7 8 if (nucnu) { 9 return nucnu 10 } 11 return ', ' 12 } 13 14 println r
Se hace uso de un lookahead negativo (?!\s)
para prohibir
la sustitución cuando la coma va seguida de un blanco.
generaciondecodigos@nereida:~/src/groovy/strings$ groovy commawhite.groovy Enter string: 2,3,4,a,b,5,6,c,d, e,f,g 2,3, 4, a, b, 5,6, c, d, e, f, g