1

.Net で正規表現に否定を適用しようとしています。それは動作しません。文字列に有効な姓がある場合、正規表現は一致してはなりません。姓が無効な場合は、一致する必要があります。有効な名前には、文字、スペース、一重引用符、および 1 ~ 40 の長さのみを使用できます。誰かが XML を解析することを提案しましたが、私はそうしたくありません。正規表現で否定を削除し、コードで一致条件を反転することで、これを行う別の方法があることを知っています。しかし、私もそれを望んでいません。これには純粋な正規表現ソリューションが必要です。

これが私のコードです。それは有効な姓と一致します。でも合わせたくない。

string toBevalidated = @"<FirstName>SomeName</FirstName><LastName>Some</LastName><Address1>Addre1</Address1>";
        var regex = new Regex(@"<LastName>([^a-zA-Z'\s])|(.{41,})</LastName>");
        var match = regex.Match(toBevalidated);

        // Check to see if a match was found
        if (match.Success)
        {
            Console.WriteLine("Success");
        }
        else
        {
            Console.WriteLine("Failed");
        }

編集:ここで混乱があります。私が意図した例をいくつか挙げましょう。姓が有効な場合、正規表現は一致しないはずです。たとえば、以下のサンプルは正規表現と一致しないはずです

ケース1

<FirstName>SomeName</FirstName><LastName>Brian</LastName><Address1>Addre1</Address1>

ケース 2

<FirstName>SomeName</FirstName><LastName>O'neil</LastName><Address1>Addre1</Address1>

ケース 3

<FirstName>SomeName</FirstName><LastName>Peter John</LastName><Address1>Addre1</Address1>

姓が無効な場合、正規表現は一致する必要があります

ケース4

<FirstName>SomeName</FirstName><LastName>Brian123</LastName><Address1>Addre1</Address1>

ケース5

<FirstName>SomeName</FirstName><LastName>#Brian</LastName><Address1>Addre1</Address1>

ケース6

<FirstName>SomeName</FirstName><LastName>BrianBrianBrianBrianBrianBrianBrianBrianBrianBrian</LastName><Address1>Addre1</Address1>

さらに情報が必要な場合はお知らせください

4

3 に答える 3

1

これが期待どおりに動作しない例を示していただければ助かります、無効な文字が1つだけの場合にのみ無効な文字に一致するためだと思います。

<LastName>5</LastName>

それは一致します(私は信じています;私はチェックしていません)が、これは一致しません:

<LastName>55</LastName>

次のようなことができると思います:

<LastName>(.*[^a-zA-Z'\s].*)|(.{41,})</LastName>

そこに少なくとも1 つの無効な文字がある (または 41 文字以上ある) ことを確認します。しかし、それが不適切なまれなケースがここにあるかもしれません。

編集:わかりました。代替演算子は、前のグループだけでなく、その前のすべてをオプションとして使用していました。最終的な正規表現は次のとおりです。

<LastName>((.*[^a-zA-Z'\s].*)|(.{41,}))</LastName>

そして、ここにいくつかのサンプルコードがあります:

using System;
using System.Text.RegularExpressions;

class Test
{
    static void Main()
    {
        string pattern = @"<LastName>((.*[^a-zA-Z'\s].*)|(.{41,}))</LastName>";
        Regex regex = new Regex(pattern);

        string[] samples = {
            "<FirstName>SomeName</FirstName><LastName>Brian</LastName><Address1>Addre1</Address1>",
            "<FirstName>SomeName</FirstName><LastName>O'neil</LastName><Address1>Addre1</Address1>",
            "<FirstName>SomeName</FirstName><LastName>Peter John</LastName><Address1>Addre1</Address1>",
            "<FirstName>SomeName</FirstName><LastName>Brian123</LastName><Address1>Addre1</Address1>",                
            "<FirstName>SomeName</FirstName><LastName>#Brian</LastName><Address1>Addre1</Address1>",
            "<FirstName>SomeName</FirstName><LastName>BrianBrianBrianBrianBrianBrianBrianBrianBrianBrian</LastName><Address1>Addre1</Address1>",
        };

        foreach (var sample in samples)
        {
            bool valid = !regex.IsMatch(sample);
            Console.WriteLine("Valid: {0} Text: {1}", valid, sample);
        }
    }
}
于 2010-10-28T15:20:32.653 に答える
0

Ok、

1 回のパスでは動作しませんでしたが、2 回のパスで実行するとうまくいくと思います。最初に間違った文字をチェックし、2 回目のパスで長さをチェックします。

Match m = Regex.Match(@"<FirstName>SomeName</FirstName><LastName>Some</LastName><Address1>Addre1</Address1>", "<LastName>(.*[^a-zA-Z'\\s].*)</LastName>");

m = Regex.Match(@"<FirstName>SomeName</FirstName><LastName>SomeSomSomeSomeSomeSomeSomeSomeSomeSomeeSomeSomeSomeSomeSomeSomeSome</LastName><Address1>Addre1</Address1>", "<LastName>[a-zA-Z'\\s]{41,}</LastName>");

あなたが提供したすべてのケースをチェックしたわけではありません。チェックして、うまくいくかどうか教えてください。

修正してくれたスキートに感謝します。[^a-zA-Z'\s]. 前後に .* が必要です。そうしないと、特殊文字を含む名前と一致しません。

長さをチェックする正規表現パターンの 2 番目の部分は、すべてのものと一致するため、機能しません。

幸運を。

于 2010-10-28T16:46:37.650 に答える
0

正規表現を次のように書き換えてみてください: <LastName>([a-zA-Z'\s]{0,41})</LastName> 他のコードで否定を使用します:if (!match.success) ...

于 2010-10-28T15:18:47.390 に答える