我有一个这样的文本文件:
Start
<Not Present>
Start
<Word>
End
Start
<Word>
End
Start
<Antoher>
End
End
我必须编写一个regEx,仅提供包含<Word>
的“Start ... End”块。
我尝试过这样的事情:
(Start[\s\S]+?(<Word>.*)[\s\S]+?End)
我得到两个子匹配作为结果。 第一个子匹配:
Start
<Not Present>
Start
<Word>
End
第二个子匹配:
Start
<Word>
End
你可以看到第二个是正确的,但第一个是错的。我只想要<Word>
在“开始......结束”块中的子匹配。
我该怎么做?
谢谢。
答案 0 :(得分:1)
(?s)Start(?:(?!Start|End).)*<Word>(?:(?!End).)*End
(?!Start|End).
匹配任何一个字符(包括\n
,感谢(?s)
修饰符),除非它是Start
或End
的第一个字符。这样可以确保您只匹配最里面的Start
和End
分隔符。
我在单线模式下使用.
(通过内联(?s)
修饰符)来匹配任何字符,包括换行符,因为您提到MatchCollection
,表示您'重新使用.NET正则表达式的味道。 [\s\S]
hack通常只在JavaScript中需要。
更正:我原以为你在谈论.NET框架中的类System.Text.RegularExpressions.MatchCollection
,但我刚刚知道VBScript还包含一个名为MatchCollection
的类。它可能是你正在使用的VBScript风格(通过ActiveX或COM),所以正则表达式应该是:
Start(?:(?!Start|End)[\S\s])*<Word>(?:(?!End)[\S\s])*End
对此感到抱歉。更多信息here。
答案 1 :(得分:0)
两个问题:
?
即可使其变得非贪婪。如果没有这个,它将匹配跨越两个对的Start
和End
- 第一个Start
和第二个End
- 并将其放在<Word>
[\s\S]
匹配所有内容 - 它与点.
相同。您只需要空格[\s]
试试这个(你也可以删除多余的外括号):
Start(.*?<Word>.*?)End
答案 2 :(得分:0)
[\s\S]
没有多大意义。 \s
匹配空格,而\S
则完全相反 - 它匹配非空格。因此[\s\S]
几乎等同于.
。
我也不确定在.*
之后使用<Word>
想要实现的目标。这只会匹配<Word>
之后的空格。
(Start[\s]+(<Word>)[\s]+End)
据我所知,它适用于http://regexpal.com/中的测试用例。