代码之家  ›  专栏  ›  技术社区  ›  Nostromo

正则表达式查找标记

  •  3
  • Nostromo  · 技术社区  · 7 年前

    我肯定有人问过这个问题,但我不知道在谷歌上搜索什么词才能找到这些答案。

    我必须将带有标记的文本“翻译”为html(或rtf或xaml)。“粗体”的标记为*。如果我希望粗体文本包含文字*我必须用反斜杠将其屏蔽。

    所以,标记的文本。。。

    This is *ju\*st* a test.
    

    朱*街

    我正在寻找一个正则表达式模式,以便在标记文本中将所有匹配项“翻译”为粗体。

    现在我只能用这个(一个字面值的星号后跟一个或多个非星号的字符(尽可能少),后跟一个字面值的星号)

    \*[^*]+?\*
    

    但是我怎样才能增强“一个或多个非星号的字符”部分,使其不停在前面有反斜杠的星号上呢?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Right leg A.s. Bhullar    7 年前

    您希望从一个标记星匹配到另一个标记星。 在标记语言中,文字星号实际上不仅仅是 * 但是 \* . 在正则表达式中,这可以翻译为 \\\*

    因此,您需要在模式中指定要查找的 标记星 ,而不是 文学明星 .

    \*.*[^\\]\*
    
    \*             a markup star
      .*           followed by any character
        [^\\]\*    then a markup star, that is, one not escaped by a backslash
    

    这有点不对劲,因为 .* 是贪心,所以在 "*ju\*st* *ju\*st* 从第一颗星到最后一颗星,它将匹配整个字符串。

    可以使用星形修改器的惰性/非贪婪版本: *? 在大多数发动机中。

    \*.*?[^\\]\*
    
    \*             a markup star
      .*?          followed by any character, but as few as possible
         [^\\]\*   then a markup star, that is, one not escaped by a backslash
    

    Python的小型尝试:

    >>> s = r"*ju\*st* *ju\*st*"
    >>> re.match(r"\*.*[^\\]\*", s)
    <re.Match object; span=(0, 17), match='*ju\\*st* *ju\\*st*'>
    >>> re.match(r"\*.*?[^\\]\*", s)
    <re.Match object; span=(0, 8), match='*ju\\*st*'>
    

    如果您的正则表达式引擎不支持惰性修饰符,则需要明确此行为:

    \*([^*]|\\\*)*[^\\]\*
    
    \*                       a markup star
      (                      then either...
       [^*]                  ...any character but a star...
           |                 ...or...
            \\\*             ...a star prefix by a backslash, ie a literal star
                )*           any number
                  [^\\]\*    then a markup star
    
        2
  •  1
  •   Wiktor Stribiżew    7 年前

    你可以用

    (?<=(?<!\\)(?:\\{2})*)\*[^\\*]*(?:\\.[^\\*]*)*\*
    

    见 .NET regex demo .

    细节

    • (?<=(?<!\\)(?:\\{2})*) \ 当前位置前的转义字符。换句话说,它匹配的位置前面紧跟着:
      • (?<!\\) \
      • (?:\\{2})* -任何零次或多次重复的双反斜杠
    • \* -a * 烧焦
    • [^\\*]* \ 和
    • (?: -开始非捕获组匹配。。。
      • \\. -任何字符(除换行符外,使用 RegexOptions.Singleline 允许任何转义字符)使用 烧焦
      • [^\\*]* \ 和
    • )* -零次或多次
    • \* *