2017-09-13 110 views
1

我需要匹配下列字符串中的产品。他们有一个所需的前缀GENERAL REQUIREMENTS和一个可选后缀APPLICATIONS。我需要排除前缀(我得到了很多工作)和后缀(尽管我尽了最大的努力仍然包括在内)。.NET正则表达式,排除匹配中的可选后缀

GENERAL REQUIREMENTS FOR VALVE APPLICATIONS // should match "VALVE" 
GENERAL REQUIREMENTS OF FOO BAR APPLICATIONS // should match "FOO BAR" 
GENERAL REQUIREMENTS FOR DURDLES // should match "DURDLES" 

我现在的正则表达式:

(?<=GENERAL REQUIREMENTS FOR |OF).*(?=APPLICATIONS)? 

是包括比赛APPLICATIONS的第2位。

编辑:有没有办法排除可选的前缀和后缀,同时要求至少存在一个?这是我的单元测试的样子;我建立起来,我们发现更多的特殊情况(断言使用FluentAssertions):

[Theory] 
    [InlineData("", "")] 
    [InlineData("NO CATEGORY HERE", "")] 
    [InlineData("GENERAL REQUIREMENTS FOR VALVE APPLICATIONS", "VALVE")] 
    [InlineData("GENERAL VALVE REQUIREMENTS", "VALVE")] 
    [InlineData("VALVE REQUIREMENTS", "VALVE")] 
    [InlineData("INSTALLATION OF VALVES", "VALVES")] 
    public void ExtractProductCategoryFromArticle_ReturnsExpectedCategory(string articleText, string expectedCategory) 
    { 
     string actualCategory = StringUtilities.ExtractProductCategoryFromArticle(articleText); 
     actualCategory.Should().Be(expectedCategory); 
    } 

我结束了无解的正则表达式的问题,使用string.StartsWith()和string.EndsWith()检查以确保至少存在一个前缀或后缀,然后用结果中的空字符串替换这些相同的单词并对其进行修剪。

+0

为什么正则表达式。做这个。 'var teststring =“阀门应用的一般要求”;'。然后'teststring = teststring.Replace(“GENERAL REQUIREMENTS”,“”)。Replace(“APPLICATIONS”,“”)。Replace(“For”,“”)。Replace(“OF”,“”);'。你会得到'VALVE' –

+0

这是一个正则表达式的起点,这个正则表达式很可能会包含很多单词;我宁愿有一个正则表达式,而不是一堆string.Replace()语句(是的,我知道它们更快)。 –

+0

好的。 @Wiktor的答案似乎已经足够:) –

回答

2

你可以让你的正则表达式结构,但在结尾处,删除?,使.*懒:

(?<=GENERAL REQUIREMENTS FOR |OF).*?(?=APPLICATIONS|$) 
            ^    ^^ 

$将使它也匹配字符串的结尾(.*?将匹配到字符串末尾)和.*?将尽可能少的字符匹配。

请参阅regex demo

但是,您也可以捕捉你需要摆脱昂贵的回顾后的部分:

(?:GENERAL REQUIREMENTS FOR|OF)\s*(.*?)(?:APPLICATIONS|$) 

another regex demo

用法示例:

var res = Regex.Matches(s, @"(?:GENERAL REQUIREMENTS FOR|OF)\s*(.*?)(?:APPLICATIONS|$)") 
    .Cast<Match>() 
    .Select(x => x.Groups[1].Value) 
    .ToList(); 

enter image description here