查找单词的最后一次出现

时间:2008-11-25 09:53:46

标签: c# .net regex last-occurrence

我有以下字符串:

<SEM>electric</SEM> cu <SEM>hello</SEM> rent <SEM>is<I>love</I>, <PARTITION />mind

我想在“PARTITION”标签之前找到最后一个“SEM”开始标签。不是SEM结束标签,而是开始标签。结果应该是:

<SEM>is <Im>love</Im>, <PARTITION />

我试过这个正则表达式:

<SEM>[^<]*<PARTITION[ ]/>

但它仅在最终的“SEM”和“PARTITION”标签之间没有任何其他标签时才有效。有什么想法吗?

6 个答案:

答案 0 :(得分:7)

使用String.IndexOf查找PARTITION并使用String.LastIndexOf查找SEM?

int partitionIndex = text.IndexOf("<PARTITION");
int emIndex = text.LastIndexOf("<SEM>", partitionIndex);

答案 1 :(得分:3)

这是你愚蠢的正则表达式!!!

(?=[\s\S]*?\<PARTITION)(?![\s\S]+?\<SEM\>)\<SEM\>

这说的是“虽然前方某处是PARTITION标签......但前方不是另一个SEM标签......匹配SEM标签。”

享受!

这是正则表达式的细分:

(?=[\s\S]*?\<PARTITION) means "While ahead somewhere is a PARTITION tag"
(?![\s\S]+?\<SEM\>) means "While ahead somewhere is not a SEM tag"
\<SEM\> means "Match a SEM tag"

答案 2 :(得分:2)

如果您要使用正则表达式查找最后一次出现的内容,那么您可能还想使用从右到左解析的正则表达式选项:

new Regex("...", RegexOptions.RightToLeft);

答案 3 :(得分:1)

解决方案就是这个,我在http://regexlib.com/RETester.aspx

进行了测试
<\s*SEM\s*>(?!.*</SEM>.*).*<\s*PARTITION\s*/> 

如果您想要最后一个,唯一的识别方法是仅查找不包含</SEM>的字符。

如果<SEM> or <PARTITION/>中有一些空格,我已加入“\ s *”。

基本上,我们所做的是将</SEM>排除在:

之后
(?!.*</SEM>.*)

答案 4 :(得分:0)

你试过这个:

<EM>.*<PARTITION\s*/>

你的正则表达式匹配任何东西,但“&lt;”在“EM”标签之后。因此,当它点击关闭的“EM”标签时它会停止匹配。

答案 5 :(得分:0)

有点肮脏,但试试这个:

(<SEM>.*?</SEM>.*?)*(<SEM>.*?<PARTITION)

并查看C#/。净当量$ 2

中的内容

秘密在于懒惰匹配构造(。*?)---我假设/希望C#支持这个。

显然,Jon Skeet的解决方案性能会更好,但您可能希望使用正则表达式(例如,简化分解您感兴趣的位)。

(免责声明:我自己是Perl / Python / Ruby人......)