Eu tenho esse código e quero saber se posso substituir apenas grupos (não todos os padrões) no Java regex. Código:
//...
Pattern p = Pattern.compile("(\\d).*(\\d)");
String input = "6 example input 4";
Matcher m = p.matcher(input);
if (m.find()) {
//Now I want replace group one ( (\\d) ) with number
//and group two (too (\\d) ) with 1, but I don't know how.
}
java
regex
replace
regex-group
wokena
fonte
fonte
Respostas:
Use
$n
(onde n é um dígito) para se referir às subsequências capturadas emreplaceFirst(...)
. Presumo que você queira substituir o primeiro grupo pela string literal "número" e o segundo grupo pelo valor do primeiro grupo.Considere
(\D+)
para o segundo grupo em vez de(.*)
.*
é um matcher ganancioso e, a princípio, consumirá o último dígito. O combinador terá então que retroceder quando perceber que a final(\d)
não tem nada a corresponder, antes que possa corresponder ao dígito final.fonte
m.replaceFirst("number $2$1");
deveria serm.replaceFirst("number $3$1");
Você pode usar
Matcher#start(group)
eMatcher#end(group)
para construir um método de substituição genérico:Verifique a demonstração online aqui .
fonte
Desculpe bater em um cavalo morto, mas é meio estranho que ninguém apontou isso - "Sim, você pode, mas isso é o oposto de como você usa a captura de grupos na vida real".
Se você usar o Regex da maneira que deve ser usado, a solução é tão simples quanto esta:
Ou, conforme indicado por shmosel abaixo,
... já que na sua regex não há nenhuma boa razão para agrupar os decimais.
Você não costuma usar grupos de captura nas partes da corda que deseja descartar , você os usa na parte da corda que deseja manter .
Se você realmente deseja grupos que deseja substituir, o que provavelmente deseja é um mecanismo de modelagem (por exemplo, bigode, ejs, StringTemplate, ...).
Como um aparte para os curiosos, mesmo os grupos que não capturam em regexes estão lá apenas para o caso de o mecanismo de regex precisar deles para reconhecer e pular o texto variável. Por exemplo, em
você precisa deles se sua entrada puder ser semelhante a "abcabc capture me bcdbcd" ou "abc capture me bcd" ou mesmo apenas "capture me".
Ou, dito de outra forma: se o texto é sempre o mesmo e você não o captura, não há razão para usar grupos.
fonte
\d(.*)\d
será suficiente.$11
aqui. Por que 11?Adicione um terceiro grupo adicionando parênteses ao redor
.*
, então substitua a subsequência por"number" + m.group(2) + "1"
. por exemplo:fonte
"number$21"
funciona e"number" + m.group(2) + "1"
não funciona .number$21
iria substituir o grupo 21, não o grupo 2 + a string "1".Você pode usar os métodos matcher.start () e matcher.end () para obter as posições do grupo. Assim, usando essas posições, você pode facilmente substituir qualquer texto.
fonte
substitua os campos de senha da entrada:
fonte
Aqui está uma solução diferente, que também permite a substituição de um único grupo em várias correspondências. Ele usa pilhas para reverter a ordem de execução, de forma que a operação da string possa ser executada com segurança.
fonte