正则表达式 + 删除匹配前的所有文本

8
我正在尝试找到一种方法,在正则表达式中匹配前删除字符串中的所有文本。我正在使用C#进行编程。
例如,如果字符串是“hello, test matching”,模式是“test”,我希望最终结果为“test matching”(即删除“test”之前的所有内容)。
有什么想法吗?谢谢!
编辑:在阅读您的回复后(感谢您的回复),我可能应该在我的示例中更具体一些。我喜欢预查方法,但我过于简化了我的示例。通常,字符串看起来像:
“hello,test matching test everythingAfter”
因此,如果我使用模式“test”,它将捕获第一个匹配项。我的目标是替换第二个匹配项后的所有文本。即:得到“test everythingAfter”的结果... 对此表示抱歉。

2
我对C#不够熟悉,无法编写代码。但是,请勿使用正则表达式,而是使用基本的字符串方法。搜索以查找出现,然后使用子字符串捕获之后的所有内容 - Jason McCreary
你想要删除的模式,它们总是字符串吗?还是有时候是真正的正则表达式?如果是前者,使用 IndexOfSubstring,避免不必要的性能损失。 - Platinum Azure
可能是重复问题:从字符串中删除文本,直到达到某个字符 - Ryan Gates
3个回答

8
您可以使用正向预查来匹配字符串但不捕获它:
(?=test)

所以您想捕获最后一个test出现之前的内容:

^.*(?=test)

如果你想让它匹配第一个出现的"test",则使用懒惰匹配:
^.*?(?=test)

谢谢回复 - 我已经对上面的问题进行了编辑...我喜欢那种前瞻性的方法。我可以选择第二个匹配然后再进行前瞻吗? - keynesiancross
你如何捕获出现后的所有内容? - user1040975

5

对于一个简单的解决方案,只需用"test"替换"行首 任何字符 test":

newString = Regex.Replace(oldString, "^.*test", "test");

由于 * 是贪婪的,因此它将尽可能地替换,例如:a test b test c 将变成 test c。要尽量少地替换,请使用 *? 而不是 *

如果您想避免重复搜索单词,可以使用零宽度正向先行断言

newString = Regex.Replace(oldString, "^.*(?=test)", "");

这将删除test最后一个匹配之前的所有内容。在许多情况下可能无关紧要,但也可能会令人困惑。 - svick
实际上,现在我阅读回复时,这正是我需要做的(请参见我的上面的编辑)。我需要它匹配到最后一个结果,并替换它之前的所有内容。非常感谢。 - keynesiancross
@keynesiancross:如果是这样的话,你应该接受Heinzi或我的答案,而不是Paul的。没有个人恩怨,Paul,但那个答案只是偶然有效。 - Alan Moore
只有偶然才能起作用,因为问题没有说明他只想要最后一次匹配。只有在我回答后,他才发表了这个评论。 - Standage

1

*已更新,使用MatchCollection

string test = "hello, test matching";

string regexStrTest;
regexStrTest = @"test\s\w+";       
MatchCollection m1 = Regex.Matches(test, regexStrTest);
//gets the second matched value
string value = m1[1].Value;   

这是一个向后查找,而不是向前查找,并且它没有做任何有用的事情。如果“test\s”刚刚消耗了跟随空格的测试,那么当然向后查找“test ”会成功。此外,Singleline选项没有任何影响,因为在正则表达式中未使用“.”元字符。 - Alan Moore
好的,无功能的额外代码已经删除,但是这仍然返回test第二个出现和一个单词在其后。 在对另一个回答的评论中,OP说他真正想要的是最后一次出现(@keynes应该再次更新问题),并且匹配应该包括在此之后的所有内容,而不仅仅是一个词。 - Alan Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接