C# 正则表达式子字符串应该在开始和结束但不在中间

Posted

技术标签:

【中文标题】C# 正则表达式子字符串应该在开始和结束但不在中间【英文标题】:C# Regex substring should be at start and end but not in the middle 【发布时间】:2021-10-01 00:19:59 【问题描述】:

让我们考虑$ 开始标签和$ 结束标签。开始标签应该只出现在开始和结束标签上。字符 ,,$ 是允许的,只要它们不构成标签之一:所以 $MacroInner$ 是允许的。

这是我尝试过的:\$\[^((\$\)|(\\$))]+\\$

【问题讨论】:

【参考方案1】:

如果卷曲不必是平衡,您可以使用

(?<!\S)\$[^]*(?>(?:(?<!\$)|(?!\$))[^]*)*\$(?!\S)

模式匹配:

(?&lt;!\S) 向左声明空白边界 \$ 匹配 $ [^]* 可选择重复匹配除 以外的任何字符 (?&gt;原子团 (?:非捕获组 (?&lt;!\$) 匹配 断言不是 到左边 |或者 (?!\$) 匹配 断言不是 到右边 )关闭非捕获组 [^]* 可选择重复匹配除 之外的任何字符 )*关闭原子组并可选择重复 \$匹配$ (?!\S) 断言右边的空白边界

.NET regex demo


如果括号应该是平衡的,你可以使用:

(?<!\S)\$(?>(?<!\$)(?<c>)|[^]+|(?!\$)(?<-c>))*(?(c)(?!))\$(?!\S)

Regex demo

【讨论】:

【参考方案2】:

这个不需要正则表达式

s.StartsWith("$") && s.EndsWith("$") && new[]"$", "$".All(x => x.IndexOf(x, 2, s.Length-4) == -1)

为什么我提倡不使用正则表达式?

寻求简单的解决方案,而不是完美的解决方案; 此代码更具可读性/自我记录 它并不是一个复杂的正则表达式,以至于您必须要求 SO 才能使其工作 与所需复杂性的正则表达式相比,您或替代您的开发人员有更合理的机会维护它

【讨论】:

【参考方案3】:

您已尝试使用[^((\$\)|(\\$))]+ 模式来防止匹配$$,但这是对character groups 工作原理的误解。

[^((\$\)|(\\$))] 表示匹配不是($)| 的单个字符。

以下工作正则表达式是如何使用 negative lookahead 来避免匹配 $$ 的示例:

\$\(?:(?!\$\|\\$).)*\\$

如果您想跨换行符匹配,请使用RegexOptions.Singleline

(虽然我已经这样做了,但没有必要在上面的正则表达式中转义,因为正则表达式引擎可以从周围的上下文中确定它们应该被解释为与文字字符匹配。)

【讨论】:

以上是关于C# 正则表达式子字符串应该在开始和结束但不在中间的主要内容,如果未能解决你的问题,请参考以下文章

匹配 XML 字符串的正则表达式在 C# 中具有开始和结束标记

C# 正则表达式提取指定文本内的内容

C# 正则表达式提取指定文本内的内容

C# 正则表达式提取指定文本内的内容

C# 正则表达式提取指定文本内的内容

初步学习正则表达式