4

文字列が「SIGSEC」でない限り、「PRI」または「SEC」で終わる長さ 6 文字の文字列に一致させるために、次の正規表現パターンを作成しました。たとえば、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

もっと読みやすいコードを使ってみませんか?私の意見では、これははるかに保守可能です。

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 に答える
1

これを試すことができます:

@"\w{3}(?:PRI|(?<!SIG)SEC)"
  • 3 つの「単語」文字に一致
  • PRI または SEC に一致します (ただし、SIG の後ではなく、つまり SIGSEC は除外されます) (? < !x)y - 負の後読みです (x が前にない場合、y を計算します)

また、後で「SIG」以外に除外を追加する必要があるかもしれませんが、これはおそらくあまりうまくスケーリングできないことに気付きます

私のコードを使用すると、別の例外を簡単に追加できます。たとえば、次のコードは SIGSEC と FOOSEC を除外します。

@"\w{3}(?:PRI|(?<!SIG|FOO)SEC)"
于 2008-10-16T02:56:06.160 に答える
0

個人的には、2 番目の変数を使用して除外リストを作成し、それを完全な式に含める傾向があります。これは、複雑な式を作成する必要があるときに過去に使用したアプローチです。

何かのようなもの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' ) )

明確にする。それはまさにあなたが望んでいたことをしています:

  • 3 つの単語文字の後に PRI または SEC が続き、
  • SIGSEC ではない

すべてを 1 つの正規表現に強制する必要があるとは誰も言いません。

于 2008-10-16T02:56:03.057 に答える