c# - 被零宽度正向后断言的正则表达式所困扰

标签 c# regex

我有一个字符串,我想查找所有不属于 HTML 标记的大于号字符。

忽略 CDATA 等,这应该很容易:找到任何前面没有“<”的“>”字符,或者它们之间有另一个“>”。

这是我想出的第一个尝试的解决方案:

 (?<=(^|>)[^<]*)>

认为这应该查找左侧没有“<”字符的任何“>”,要么返回到字符串的开头,要么返回到上一个“>” ”。

我也尝试用负面的措辞:

 (?<!<[^>]*)>

即,“>”前面也不带有“<”,除非后面仅跟有非“>”字符。

我怀疑我只是对lookbehind 的工作原理感到困惑。

单元测试:

 No match in: <foo>
 No match in: <foo bar>
 Match in: <foo> bar>
 Match in: foo> bar
 Match in: >foo
 Two matches in: foo>>
 Two matches in: <foo> >bar>

用例:我正在从类似 wiki 的表单字段中清除 HTML,该表单字段接受一些 HTML 标记,但用户不太懂 HTML,有时会输入未转义的“>”和“<”实际小于和大于含义的文字。我的目的是用 HTML 实体替换它们,但前提是它们不是 HTML 标记的一部分。我知道他们有可能输入“高度 < 10 且 > 5”之类的文本,这会破坏这一点,但这是我可以解决或接受的边缘情况。

最佳答案

这比乍一看要棘手得多(正如您所发现的)。从另一个方向来实现要容易得多:使用一个正则表达式来匹配 HTML 标签或尖括号。如果这是您找到的标签,则将其重新插入;否则你就转换它。带有 MatchEvaluator 参数的 Replace 方法非常适合:

static string ScrubInput(string input)
{
  return Regex.Replace(input, @"</?\w+>|[<>]", GetReplacement);
}

static string GetReplacement(Match m)
{
  switch (m.Value)
  {
    case "<":
      return "&lt;";
    case ">":
      return "&gt;";
    default:
      return m.Value;
  }
}

您会注意到我的标签正则表达式 -- </?\w+> ——比你的限制更多。我不知道我的是否完全适合您的需求,但我建议不要使用 <[^<>]+> -- 它会在类似 "if (x<3||x>9)" 中找到匹配项.

关于c# - 被零宽度正向后断言的正则表达式所困扰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1369510/

相关文章:

c# - Silverlight 编程绘图(从 Windows 窗体转换为 Silverlight)

php - 从文本中删除 anchor

Python正则表达式删除模式匹配中的空格

c# - Contains 中的正则表达式

python - 使用正则表达式替换文件中的字符串

c# - 基于相似性比较字符串

c# - 如何将 dd/mm/yyyy 转换为 dd/mm/yyyy

c# - 检查两个可枚举之间是否存在共同的单个元素的最快方法

c# - OOP - 两个表到同一个对象

JavaScript 正则表达式 : inserting span tag for each character