如果字符串的前面没有某些字符,我该如何匹配?

时间:2008-10-16 02:46:41

标签: c# .net regex negative-lookbehind

我创建了以下正则表达式模式,试图匹配长度为6个字符的字符串,以“PRI”或“SEC”结尾,除非string =“SIGSEC”。例如,我想匹配ABCPRI,XYZPRI,ABCSEC和XYZSEC,但不匹配SIGSEC。

(\w{3}PRI$|[^SIG].*SEC$)

这是非常接近和一些工作(如果我传入“SINSEC”,它返回“NSEC”的部分匹配),但我对它的当前形式没有很好的感觉。此外,我可能需要在“SIG”之后添加更多排除项,并意识到这可能不会扩展得太好。有什么想法吗?

BTW,我在C#中使用System.Text.RegularExpressions.Regex.Match()

谢谢, 富

8 个答案:

答案 0 :(得分:6)

假设你的正则表达式引擎支持负向前瞻,试试这个:

((?!SIGSEC)\w{3}(?:SEC|PRI))

编辑:一位评论者指出.NET确实支持负向前瞻,所以这应该可以正常工作(谢谢,查理)。

答案 1 :(得分:2)

为了帮助分解Dan的(正确)答案,以下是它的工作原理:

(           // outer capturing group to bind everything
 (?!SIGSEC) // negative lookahead: a match only works if "SIGSEC" does not appear next
 \w{3}      // exactly three "word" characters
 (?:        // non-capturing group - we don't care which of the following things matched
   SEC|PRI  // either "SEC" or "PRI"
 )
)

所有在一起:((?!SIGSEC)\ w {3}(?:SEC | PRI))

答案 2 :(得分:1)

你可以尝试这个:

@"\w{3}(?:PRI|(?<!SIG)SEC)"
  • 匹配3个“字”字符
  • 匹配PRI或SEC(但不是在SIG之后,即SIGSEC被排除在外)(?&lt;!x)y - 是负面的背后(如果它没有前面的x则计算y)
  

另外,我可能需要添加更多内容   除了“SIG”以外的排除和   意识到这可能不会扩大   太好了

使用我的代码,您可以轻松添加其他例外,例如以下代码不包括SIGSEC和FOOSEC

@"\w{3}(?:PRI|(?<!SIG|FOO)SEC)"

答案 3 :(得分:1)

为什么不使用更易读的代码?在我看来,这更易于维护。

private Boolean HasValidEnding(String input)
{
    if (input.EndsWith("SEC",StringComparison.Ordinal) || input.EndsWith("PRI",StringComparison.Ordinal))
    {
        if (!input.Equals("SIGSEC",StringComparison.Ordinal))
        {
            return true;
        }
    }
    return false;
}

或一行

private Boolean HasValidEnding(String input)
{
    return (input.EndsWith("SEC",StringComparison.Ordinal) || input.EndsWith("PRI",StringComparison.Ordinal)) && !input.Equals("SIGSEC",StringComparison.Ordinal);
}

并不是我不使用正则表达式,但在这种情况下我不会使用它们。

答案 4 :(得分:0)

就个人而言,我倾向于使用第二个变量构建排除列表,然后将其包含在完整表达式中 - 这是我过去在构建任何复杂表达。

exclude = 'someexpression'; prefix = 'list of prefixes'; suffix = 'list of suffixes'; expression = '{prefix}{exclude}{suffix}';

这样的东西

答案 5 :(得分:0)

“有些人在面对问题时,会想'我知道,我会使用正则表达式'。”现在他们有两个问题。“ -Jamie Zawinski

答案 6 :(得分:0)

您甚至可能不想在正则表达式中进行排除。例如,如果这是Perl(我不知道C#,但你可以跟随),我会这样做

if ( ( $str =~ /^\w{3}(?:PRI|SEC)$/ ) && ( $str ne 'SIGSEC' ) )

要清楚。它正是你想要的:

  • 三个字符,后跟PRI或SEC,
  • 这不是SIGSEC

没有人说你必须把所有东西都强制成一个正则表达式。

答案 7 :(得分:-1)

从RegExBuddy.com获取Regexbuddy这是一个非常简单的工具,可以帮助您轻松找出最复杂的正则表达式。