我需要匹配以下字符串中的产品。它们具有必需的前缀GENERAL REQUIREMENTS
和可选的后缀APPLICATIONS
。我需要排除前缀(我工作得很多)和后缀(尽管我付出了最大的努力,仍然包括在内)。
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
。
编辑:是否有办法排除可选的前缀和后缀,同时要求至少有一个?这就是我的单元测试的样子;我正在构建它,因为我们发现了更多特殊情况(断言使用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 :(得分:2)
您可以保留正则表达式结构,但最后删除?
并使.*
懒惰:
(?<=GENERAL REQUIREMENTS FOR |OF ).*?(?=APPLICATIONS|$)
^ ^^
$
也会在字符串末尾匹配(.*?
将匹配字符串的结尾),.*?
将匹配尽可能少的字符。< / p>
请参阅regex demo。
但是,您也可以捕捉到摆脱代价高昂的背后所需的部分:
(?:GENERAL REQUIREMENTS FOR|OF)\s*(.*?)(?:APPLICATIONS|$)
使用示例:
var res = Regex.Matches(s, @"(?:GENERAL REQUIREMENTS FOR|OF)\s*(.*?)(?:APPLICATIONS|$)")
.Cast<Match>()
.Select(x => x.Groups[1].Value)
.ToList();