我有这样的文字:
before label bla bla bla aaaa<TAG1>bbbb bla bla bla bla abcd<TAG2>efgh after
和这个正则表达式:
label\W+(?:\w+\W+){1,60}?(?:.){0,}?(\<TAG1\>|\<TAG2\>)(?:.){0,}?\W+(?:\w+\W+){1,60}(?:.){0,}?(\<TAG2\>|\<TAG1\>)(?:.){0,}?
它完成了这项工作,它按预期工作但但似乎并没有真正优化。
这是一项测试:https://regex101.com/r/eS2kS6/1
基本上我必须找到一个标签,在N个单词之后我应该得到<TAG1>
或<TAG2>
并且在N个单词之后我应该得到<TAG1>
或{ {1}}。
注意:
必须将<TAG2>
或<TAG1>
视为该词的可能“子串”,这一点非常重要。有时它可能是<TAG2>
,有时是aaaa<TAG1>bbbb
。正如您在示例中所看到的,它适用于两种情况。
答案 0 :(得分:1)
通常有助于可视化正则表达式:
请注意,(?:.){0,}?
是说.*
的迂回方式。现在也很容易看出有两个相同的块可以合并,所以我们来解决这个问题:
label\W+(?:(?:\w+\W+){1,60}?.*(\<TAG1\>|\<TAG2\>).*){2}
这相当,但更短。从这里开始,问题就在于你究竟想要匹配什么。所有\w
和\W
对我来说都有些奇怪,特别是与.
一起使用时。我通常更喜欢匹配\s
而不是\W
,因为我通常的意思是&#34;某种空白&#34;,但您需要确定您实际需要的是什么。< / p>
&#34;匹配 - 一到六十个单词 - 而不是单词 - 后跟任何&#34;您正在使用的模式((?:\w+\W+){1,60}?.*
)可能不是您想要的模式 - 例如它匹配a$<TAG
,但不匹配a<TAG
。如果您想允许一个或多个单词,请尝试(?:\s*\w+)+
。这匹配零或多个空格,后跟一个或多个字符,一次或多次。如果您希望将其限制为60
,则可以使用+
替换最终的{1,60}
(但您的说明中不清楚60
来自何处label\s+(?:(?:\w+\s*)+(\<TAG1\>|\<TAG2\>)\w*){2}
- 你需要吗?)。
所以我们现在就在这里:
after
这与您之前的模式完全相同 - 它与您的示例字符串中的.*
不匹配(从您的描述中不清楚)是否应该)。如果您想在第二个标记之后保持匹配,只需在末尾添加N
。
所有这一切,它看起来很像你试图解析一个复杂的语法(即non-regular language),那就是rife with peril。如果您发现自己编写并重写正则表达式以尝试捕获所需的数据,则可能需要升级到正确的上下文解析器。
特别是,正则表达式和我的调整都没有强制N
每次都相同。您的说明听起来似乎只想匹配第一个标记之前有N
个字词的字符串,以及它与第二个标记之间的$("html, body").animate({ scrollTop: $(document).height() }, "slow");
字。使用正则表达式可以实现这种匹配,但它肯定不会干净。如果这是一项要求,正则表达式可能不是正确的工具。