0

我有一个这样的文本文件:

Start
<Not Present>

   Start
  <Word>
   End

   Start 
   <Word>
   End

   Start 
   <Antoher>
   End    

End

我必须编写一个正则表达式,结果只提供包含<Word>.

我试过这样的事情:

(Start[\s\S]+?(<Word>.*)[\s\S]+?End)

结果我得到了两个子匹配。第一个子匹配:

Start
<Not Present>

   Start
  <Word>
   End

第二个子匹配:

   Start 
   <Word>
   End

如您所见,第二个是正确的,但第一个是错误的。我只想要<Word>“开始...结束”块内的子匹配。

我怎样才能做到这一点?

谢谢你。

4

3 回答 3

1
(?s)Start(?:(?!Start|End).)*<Word>(?:(?!End).)*End

(?!Start|End).匹配任何一个字符(包括\n,感谢(?s)修饰符),除非它是Startor的第一个字符End。这确保您只匹配最里面的一组StartEnd分隔符。

.在单行模式下使用(通过 inline(?s)修饰符)匹配任何字符,包括换行符,因为您提到MatchCollection了 ,表明您使用的是 .NET 正则表达式风格。这种[\s\S]hack 通常只在 JavaScript 中需要。


更正: 我假设您在谈论System.Text.RegularExpressions.MatchCollection.NET 框架中的类,但我刚刚了解到 VBScript 还包含一个名为MatchCollection. 它可能是您正在使用的 VBScript 风格(通过 ActiveX 或 COM),因此正则表达式应该是:

Start(?:(?!Start|End)[\S\s])*<Word>(?:(?!End)[\S\s])*End

很抱歉造成混乱。更多信息在这里

于 2012-09-11T14:24:07.893 回答
0

两个问题:

  1. 您正在使用“贪婪”匹配 - 只需添加 a?使其不贪婪。如果没有这个,它将匹配 aStart并且End跨越对 - 第一对Start和第二对End- 并将其放在开头和结尾<Word>
  2. 表达式[\s\S]匹配所有内容 - 它与 dot 相同.。你只想要空白[\s]

试试这个(你也可以删除多余的外括号):

Start(.*?<Word>.*?)End
于 2012-09-11T13:58:50.053 回答
0

[\s\S]没有多大意义。\s匹配空格并\S完全相反 - 它匹配非空格。所以[\s\S]几乎等同于..

我也不确定你想用.*after实现什么<Word>。那只会匹配 . 之后的空格<Word>

(Start[\s]+(<Word>)[\s]+End)

据我所知,它适用于http://regexpal.com/中的测试用例。

于 2012-09-11T14:06:27.367 回答