如何改进此正则表达式,使其在字符串位于注释中时不匹配

How to improve this regex to not matches when the strings are in comments

本文关键字:于注释 注释 不匹配 字符串 正则表达式 何改进      更新时间:2023-09-26

给定此示例文本:

<input type="text" value="<? print(variable); ?>">
<? /*<br><br><small>Data:</small>
<input type="text" value="<? print(data); ?>"> */ ?>
<textarea><? print(yuppy); ?></textarea>

要捕获<>我使用:

/<'?'s*(['s'S]+?)'s*'?>/g

这个正则表达式的问题是,它甚至会匹配<>/**///(注释)中,这不是所需的行为。

当这些字符串不在注释中时,我如何改进regex以正确匹配它们?


需要明确的是,正确的匹配应该是:

1) print(variable);
2) /*<br><br><small>Data:</small>
<input type="text" value="<? print(data); ?>"> */
3) print(yuppy);

相反,使用我的正则表达式,第二个匹配项是:

/*<br><br><small>Data:</small>
<input type="text" value="<? print(data);

更新:

Josh Crozier的答案几乎是好的,但有点bug:

他的正则表达式<'?'s*((?:.*'/'*['s'S]+'*'/.*)|(?:['s'S]+?))'s*'?>与https://regex101.com/r/oL5iV0/2:

<? /* hello */ ?>
html
<? /* world*/ ?>

甚至与https://regex101.com/r/qW7mR7/1:

<input type="text" value="<? print(code); ?>"> <? /* */ ?>

在最新的示例中,只有当存在换行符时,它才正确匹配。在第一个例子中,即使有换行符,它也不能正确匹配

您可以使用一个替换((?:.*'/'*['s'S]+'*'/.*)|(?:['s'S]+?))来覆盖这两种情况。

此处示例

/<'?'s*((?:.*'/'*['s'S]+'*'/.*)|(?:['s'S]+?))'s*'?>/g

它将尝试匹配注释之间和周围的所有内容(.*'/'*['s'S]+'*'/.*),或者将匹配(['s'S]+?),这是您最初拥有的内容。

输出:

1) print(variable);
2) /*<br><br><small>Data:</small>
<input type="text" value="<? print(data); ?>"> */
3) print(yuppy);

您可以使用此模式(删除空格和注释以使其与javascript一起工作):

<'?  # opening tag
[^?'/]* # all that is not a ? or a /
(?:
    '/ # a slash:
    (?:
        (?!['/*]) [^?'/]*  # - not followed by a slash or a *
      |
        '/.*(?:'n[^?'/]*)? # - that starts a single line comment
      | 
        '*                 # - that starts a multiline comment
        [^*]* (?:'*+(?!'/)[^*]*)* # (comment content)
        (?:'*'/ [^?'/]* | $)      # */ is optional
    )
  |
  '?(?!>) [^?'/]* # a ? not followed by a >
)*
(?:'?>|$) # optional closing tag ?>

演示

请注意,此模式不会导致catastropic回溯,因为在<'?之后,所有内容都是可选的,特别是结束标记?>和多行注释*/的末尾。