2017-09-13 132 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