我有根很长的绳子:
(今天是一个忧郁的日子)(今天是一个美好的日子)(今天是一个坏的日)(今天是一个绿色的日子)(今天是一个忧郁的日子)
我想要匹配括号组,除非它包含大写单词。这个词将永远是完全大写的,但可能不是唯一的全大写词--但它将是唯一一个非常糟糕的词。
我有一个非常长的字符串,我想更改括号组,这些组不包含单词BAD,而只保留BAD。我希望避免对每个括号组进行迭代,以检查它是否包含坏的内容。
这个:\(.+?\)
将与我的括号组匹配。
我试过:
\(.+?(?=\bBAD\b).+?\) -这将每个组匹配到包含坏的组。
(?=\bBAD\b).+?\) -这与小组“糟糕的一天”的结束相匹配。
我尝试了一些负面的查找,但不能让他们提供一个结果。
我知道这很管用:
\(.[^BAD]+?\)直到你包括(今天是一个蓝色的一天)-然后它失败。
有人知道有效的方法吗?
发布于 2021-11-15 14:17:10
您可以使用
\((?>([^()]*\bBAD\b)?)[^()]*\)(?(1)(?!))见.NET regex演示。详细信息
\( -a ( char(?>([^()]*\bBAD\b)?) -一个原子组(当回溯发生时不允许重新尝试它的模式):除了)和(之外,没有其他字符,然后是一个完整的单词BAD,它们都被捕获到了第1组中。[^()]* - (和)以外的零或多个字符\) -a ) char(?(1)(?!)) --如果第1组匹配,则触发回溯(在这里,由于我们以前使用了原子组,它将失败)。见C#演示
var text = "(Today is a blue day) (Today is a good day) (Today is a BAD day) (Today is a green day) (Today is a blue day)";
var matches = Regex.Matches(text, @"\((?>([^()]*\bBAD\b)?)[^()]*\)(?(1)(?!))")
.Cast<Match>()
.Select(x => x.Value)
.ToList();输出:
(Today is a blue day)
(Today is a good day)
(Today is a green day)
(Today is a blue day)发布于 2021-11-15 13:50:11
这个部分(?=\bBAD\b).+?\)向右断言不好,然后尽可能地匹配,直到下一个)。它也可以在不使用\bBAD\b.+?\)的情况下编写。
此部分[^BAD]与除B A D以外的任何字符匹配。
您可以使用相反的方法,使用负的前瞻性,而不是在括号之间使用BAD,还可以添加单词边界\b,以防止部分匹配。
\((?![^()]*\bBAD\b[^()]*\))[^()]*\)模式匹配:
\(匹配((?![^()]*\bBAD\b[^()]*\))负前瞻,不要选择括号,后面跟着单词BAD,直到右边的第一个结束括号[^()]*匹配0+乘以除( )以外的任何字符,使用否定字符类\)匹配)https://stackoverflow.com/questions/69975424
复制相似问题