Reg Ex否定不在XML字符串中工作

时间:2010-10-28 15:14:42

标签: .net xml regex-negation

我试图在.Net中对正则表达式应用否定。这是行不通的。当字符串具有有效的姓氏时,reg ex不应匹配。对于无效的姓氏,它应该匹配。有效名称仅允许字符,空格,单引号和1-40之间的长度。有人建议解析XML,我不想这样做。我知道还有另一种方法可以通过删除reg ex中的否定并反转代码中的匹配条件来实现这一点。但我也不想那样。我需要纯粹的reg ex解决方案。

这是我的代码。这与有效的姓氏相匹配。但我不想匹配。

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");
        }

编辑: 这里有困惑让我举一些例子,我打算这样做。当姓氏有效时,reg ex不应该匹配。例如,下面的样本不应与reg ex

匹配

案例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>

当姓氏无效时,reg ex应匹配

案例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>

如果您需要更多信息,请告诉我

3 个答案:

答案 0 :(得分:1)

如果你给出一个不按预期行为的例子会有所帮助,但我怀疑它是因为你只是匹配一个无效字符,如果它是无效字符,例如

<LastName>5</LastName>

那将匹配(我相信;我没有检查过),但这不会:

<LastName>55</LastName>

认为你可以这样做:

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

确保其中至少一个无效字符(或者有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);
        }
    }
}

答案 1 :(得分:0)

尝试将RegEx重写为: <LastName>([a-zA-Z'\s]{0,41})</LastName> 并在其他代码中使用否定:if (!match.success) ...

答案 2 :(得分:0)

确定,

我无法在一次传球中得到它,但是如果你在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>");

我没有检查您提供的所有案例,请查看它并告诉我它是否有效。

感谢Skeet进行更正。 [^ a-zA-Z'\ s]。它确实需要。*之前和之后它将与包含特殊字符的名称不匹配。< / p>

检查长度的正则表达式模式的第二部分甚至匹配所有事物,这就是为什么它不起作用。

祝你好运。