【问题标题】:C# regexp negative lookaheadC# 正则表达式负前瞻
【发布时间】:2013-10-16 23:41:21
【问题描述】:

我在替换特定字符后的字符时遇到问题。例如,我想用此代码将第一个 'aa' 替换为 '33'。

 string str = "dc1aaaafg";
 string pattern = @"a{2}(?!(1))";
 Regex rgx = new Regex(pattern);
 string result = rgx.Replace(str, "33");

但结果是“dc13333fg”。它取代了“1”之后的第二组。我只需要替换像“dc133aafg”这样的第一组。我怎样才能做到这一点。我有一个大字符串,它可以替换很多,这只是一个例子。

【问题讨论】:

  • “第一个 aa”是什么意思?整个字符串中只有第一个“aa”?或者,所有“aa”前面都没有“a”?顺便说一句,这个构造(?!(1)) 是字符“1”的前瞻否定断言,并且它被封装在一个捕获组中。你来这里的目的是什么?
  • 我需要在每个 '1' 之后的第一个 'aa'

标签: c# regex


【解决方案1】:

Regex.Replace() 是全局的。它将替换与模式匹配的次数*

您可以使用Regex.Replace(String, String, Int32) 来限制操作数。

string result = rgx.Replace(str, "33", 1);

或者您将模式更改为后视。

Regex rgx = new Regex(@"(?<=1)a{2}");
string result = rgx.Replace(str, "33");

* 请注意,Replace()全局,而不是增量。在"aaaaaa" 上使用表达式a{2} 替换"ba" 将导致"bababa",而不是"bbbbba"

【讨论】:

  • 谢谢!我需要在一个字符串中进行多个替换,因此我将模式更改为后视模式,它可以工作。
【解决方案2】:

Replace 方法有一个重载,您可以在其中指定次数。指定 1 并且只匹配第一个匹配项。

string result = rgx.Replace(str, "33", 1);

【讨论】:

  • "我有一个大字符串,可以替换很多。"不是最好的英语,但我认为这意味着模式“1aa”将不止一次出现。没有 DV,因为语法有歧义。
  • @MarcL。您是否建议 OP 希望替换多次出现的模式,例如'aa',在一个大字符串内,但不是连续出现(例如,'aaaabbbbbbaaaa' 变为 '33aabbbbbb33aa')?
  • 不清楚,但我的阅读(以及其他打我一拳的人)是他想替换在 '1' 之后直接出现的每个 'aa',在一个可能的字符串中包含所述模式的多个实例。但是现在重新阅读,很可能您的解决方案是必需的。我们得看看他选择了哪个答案!
【解决方案3】:

正则表达式模式不能表示只有第一个匹配是相关的。

使用Regex.Match 获取第一个匹配的位置和长度。然后使用Substring(或Remove,后跟Insert)从旧字符串构造一个新字符串,它有你想要的替换。

【讨论】:

    【解决方案4】:

    用消极的眼光试试看:(a{2})(?&lt;!\1{2})

    (a{2}) # 'a' two times
    (?<! # negative look behind
     \1{2} # '\1' is the captured group 'a' twice to "jump" over the captured group
    )
    

    【讨论】:

    • 我认为由于 a's` 是连续的,一个简单的 (?&lt;!a)a{2} 可能就足够了。
    • 是的,既然复杂了,为什么要让它变得简单:)
    猜你喜欢
    • 2021-10-11
    • 2011-10-14
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多