4

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

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

它非常接近并且可以工作(如果我传入“SINSEC”,它会返回“NSEC”上的部分匹配),但我对它目前的形式没有很好的感觉。此外,我以后可能需要添加除“SIG”之外的更多排除项,并意识到这可能不会很好地扩展。有任何想法吗?

顺便说一句,我在 C# 中使用 System.Text.RegularExpressions.Regex.Match()

谢谢,丰富

4

6 回答 6

6

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

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

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

于 2008-10-16T02:50:12.990 回答
2

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

(           // 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))

于 2008-10-16T02:59:00.867 回答
1

你可以试试这个:

@"\w{3}(?:PRI|(?<!SIG)SEC)"
  • 匹配 3 个“单词”字符
  • 匹配 PRI 或 SEC(但不是在 SIG 之后,即 SIGSEC 被排除)

另外,我以后可能需要添加除“SIG”之外的更多排除项,并意识到这可能无法很好地扩展

使用我的代码,您可以轻松添加另一个异常,例如以下代码不包括 SIGSEC 和 FOOSEC

@"\w{3}(?:PRI|(?<!SIG|FOO)SEC)"
于 2008-10-16T02:56:06.160 回答
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);
}

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

于 2008-10-16T09:00:23.337 回答
0

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

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

于 2008-10-16T02:50:55.030 回答
0

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

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

要清楚。它正在做你想要的:

  • 三个单词字符,后跟 PRI 或 SEC,以及
  • 这不是 SIGSEC

没有人说您必须将所有内容强制转换为一个正则表达式。

于 2008-10-16T02:56:03.057 回答