【问题标题】:Reg Ex negation正则表达式否定
【发布时间】:2010-10-27 20:53:11
【问题描述】:

我正在使用 .Net。我想匹配具有除 a-z、A-Z、空格和单引号以外的字符的姓氏,字符的 len 不应介于 1-40 之间。必须匹配的字符串是一个类似这样的 XML <FirstName>SomeName</FirstName><LastName>SomeLastName</LastName><Address1>Addre1</Address1>

我写了正则表达式,但它只匹配 [a-zA-Z'.\s]{1,40} <LastName>[a-zA-Z'.\s]{1,40}</LastName> EDIT:LastName 标签丢失。但我想否定这个表达。这是可能的还是我应该采取不同的方法?

【问题讨论】:

  • 请确认。你想要求姓氏超过40个字符???您是否将您的 XML 视为您的长度的一部分?我建议使用 XML 解析器,这样您就可以处理姓氏仅用于验证......但这只是我。
  • 我说我只想匹配不在 1 到 40 之间的字符。这意味着只允许 40 个字符。 XML 不是长度的一部分。在我的情况下,我无法解析 xml。
  • 在下面编辑了我的答案...不确定您是否收到编辑通知,所以添加此评论。
  • 我没有看到回复。我修改了我的帖子,以便它可以处理 XML。我正确匹配空 XML 标记、其中任何位置具有无效数据的 XML 标记以及具有 41 个或更多字符的 XML 标记。如果您能告诉我这是否为您解决了问题,那就太好了。

标签: .net regex regex-negation


【解决方案1】:

你可以有否定的字符类。 [^abc] 匹配任何不是abc 的字符。对于您的情况,您可能需要[^a-zA-Z'.\s]{1,40}

由于您的数据在 XML 标记中,您可能希望先从这些标记中提取。 XML 和正则表达式并不总是能很好地混合使用。


如果您绝对必须处理正则表达式中的 XML 标记,您可以尝试以下操作:

<FirstName>([^a-zA-Z'.\s]{1,40})</FirstName><LastName>([^a-zA-Z'.\s]{1,40})</LastName>

捕获组 1 将是名字,捕获组 2 将是姓氏。


误读原题,如果你想匹配超过40个字符的字符串,长度应该是{41,}而不是{1,40}。这将确保您只匹配超过 40 个字符的字符串。

【讨论】:

  • 字符超过40的情况下失败
  • 由于代码限制,我无法解析 XML。这可能是对 XML 的应用否定吗?
  • 如果 XML 保持这么简单,你可以找到 &lt;FirstName&gt;&lt;/FirstName&gt;&lt;LastName&gt;&lt;/LastName&gt; 和所有地址的东西(如果你'对此不感兴趣)并替换为null,然后您进行正则表达式匹配。
  • 如果我有机会进行大量代码更改,我会使用 Match.Success == false 属性在 .Net 代码本身中应用 if 条件。但我希望在 Reg Exp 本身中实现这一点
  • @FrustratedWithFormsDesigner 我尝试使用您的 reg ex ([^a-zA-Z'.\s]{41,}) 并且它与包含数字的字符串不匹配SomeNamebrian6Addre1.
【解决方案2】:

您似乎想知道如何在不使用语言中的某些“非”类型逻辑的情况下否定模式匹配,而是将其置于模式匹配本身中。

如果这就是你真正的意思,你需要做的就是将你的"regex" 转换成"^(?:(?!regex).)*$"

第一个适用于任何包含“regex”的字符串,第二个适用于任何不包含“regex”的字符串。

我想如果你想注意多行输入字符串,那应该是 "\A(?:(?!regex)(?s).)*\z" 只是为了超级小心。

【讨论】:

  • 我试过你的 reg ex 这样 ^(?:(?!([a-zA-Z'.\s]{1,40})).)*$姓氏>。但与字符串不匹配,而不是包含 ast 名称中的数字 SomeNamebrian6Addre1
  • @amz 这是不对的。你误会了。当然它不匹配,你在模式中间有整个字符串锚。你的角色等级全错了。你必须说你不想要什么,而不是你做什么。如果你不想要一个数字,匹配你想要的,然后寻找那里是否有一个数字。恐怕复杂的正则表达式结构对于你现在的学习路径来说有点复杂。
  • 从另一个线程stackoverflow.com/questions/4044272/…得到答案
【解决方案3】:

否定字符是“^”。因此,您的表达式将如下所示:

[^a-zA-Z'\S]{1,40}.

Here is a link to Microsoft's site about negation.

享受

【讨论】:

  • 我认为插入符号只需要在其中一次,在左方括号之后。
  • @FrustratedWithFormsDesigner - 很好,是的,你是对的。谢谢!
【解决方案4】:

试试这个模式

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

【讨论】:

  • 不适用于此 SomeName。 Reg 不应该匹配上面的字符串。
  • 是的,它显然不会为此工作,因为此模式不匹配 a-z,不匹配 A-Z,不匹配 ',不匹配空格或长度 > 40 的任何字符,你提到你需要什么,你说你想要匹配英文字符、qoute 和空格以及 1 到 40 之间的长度的正则表达式的否定。
  • 如果您没有将它包含在 LastName 节点中,它将适用于您使用的测试文本,因为它匹配长度超过 40 的文本,现在试试我更新了模式
  • did not unmatch for this 'SomeNameSomeAddre1' 表示失败
【解决方案5】:

[编辑] - 删除了其他内容。这是在我的测试中适用于所有条件(包括空)的东西,包括在测试字符串中包含 XML。

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

【讨论】:

  • 是的,已经编写了 100 个过滤器。在.net中应用reg ex后,他们都在检查match.success == true。我的情况是,我无法单独为这个过滤器更改代码 match.success == false。这就是我想在不涉及 .net 代码的情况下实现所有否定的原因。
  • 我的问题中遗漏了一些 。请再次检查问题。我希望这个 reg ex 需要应用于 XML。不仅仅是提取的姓氏。
  • 我像这样修改了 reg ex ^([a-zA-Z'\s]*[^a-zA-Z'\s]+[a-zA-Z'\ s]*)|([a-zA-Z'\s]{41,}) 但不匹配包含姓氏中数字的字符串 SomeNamebrian6姓>Addre1
  • 好的,应该这样做。在上面发布了一个表达式,它也处理字符串中的 XML。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 2011-07-09
  • 2016-01-21
相关资源
最近更新 更多