正则表达式:使用给定的匹配将字符串中的字符替换为另一个字符串

3
我想用正则表达式匹配替换给定字符。例如,给定以下字符串:
If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough
我想在'ok'和'fe'之间的所有“t”替换为“!”。 我可以通过以下正则表达式获取'ok'和'fe'之间的匹配:
(?<=ok).*?(?=fe)

我只能使用以下正则表达式匹配一个字符:

(?<=ok).*?(t).*?(?=fe)

我尝试按照以下方式转换正则表达式,但它无法工作:

(?<=ok).*?((t).*?)*?(?=fe)

如何匹配在“ok”和“fe”之间的所有“t”? https://regex101.com/r/ORgseA/1
1个回答

3

您可以使用

String result = text.replaceAll("(?s)(\\G(?!\\A)|ok)((?:(?!ok|fe|t).)*)t(?=(?:(?!ok|fe).)*fe)", "$1$2!");

请查看正则表达式演示Java演示

String text = "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough";
String result = text.replaceAll("(?s)(\\G(?!\\A)|ok)((?:(?!ok|fe|t).)*)t(?=(?:(?!ok|fe).)*fe)", "$1$2!");
System.out.println(result);
// => If you look a! wha! you have in life, you'll always have more. If you look a! wha! you don'! have in life, you'll never have enough

细节:

  • (?s) - 嵌入式标志选项Pattern.DOTALL(使.匹配换行符)
  • (\G(?!\A)|ok) - 第一组 ($1): ok 或上一个成功的匹配的结尾
  • ((?:(?!ok|fe|t).)*) - 第二组 ($2): 任何一个字符,零个或多个出现次数,尽可能多,不以okfet字符序列开头
  • t - 一个t字符
  • (?=(?:(?!ok|fe).)*fe) - 立即向右侧,必须是任何单个字符,零个或多个出现次数,尽可能多,不以okfe字符序列开头,然后是fe子字符串。

1
非常好,使用\G ++。 - The fourth bird
哇,太棒了的答案。非常感谢。现在我只需要喝杯咖啡,就可以理解“细节”部分了 :) - Davide
1
@Davide 如果你想知道这些 (?:(?!xxx).)* 的含义,可以在这里阅读相关内容。 - Wiktor Stribiżew
经过分析,我想添加以下内容。如果我们想要将多个字符替换为“!”,我们只需要将所有要替换的字符括在一组中,例如(t | w | h)。如果我们不将它们括在一组中,则范围在“ok”和“fe”之外的字符也会被替换。 - Davide
1
@Davide 当然可以,但你应该考虑使用非捕获组,它们用于匹配我们需要从字符串中删除的替代模式,我们只捕获想要保留的内容。并将单个字符放入字符类中。因此,在(t|w|h)的情况下,请使用[twh]。如果你有(t|w|hd),你可以使用(?:hd|[tw]) - Wiktor Stribiżew
嗯,是的 :) 我完全同意。 - Davide

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接