【问题标题】:Negate random regular expression否定随机正则表达式
【发布时间】:2014-08-08 12:03:58
【问题描述】:

有没有办法否定任何正则表达式?我正在使用正则表达式来验证表单上的输入。我现在正在尝试创建一个按钮来清理我的输入。有没有办法让我可以使用用于验证的正则表达式来去除无效字符?

我正在使用这个正则表达式来验证非法字符

<input data-val-regex-pattern="[^|<>:\?'\*\[\]\=%\$\+,;~&\{\}]*" type="text" />

当点击它旁边的按钮时,我正在调用这个函数:

$('#button').click(function () {
    var inputElement = $(this).prev();
    var regex = new RegExp(inputElement.attr('data-val-regex-pattern'), 'g');
    var value = inputElement.val();
    inputElement.val(value.replace(regex, ''));
});

目前,javascript 正在做的事情与我想要完成的事情完全相反。我需要找到一种方法来“反转”正则表达式。

编辑: 我正在尝试反转 javascript 函数中的正则表达式。 data-val-regex-pattern-attribute 中的正则表达式正在完成他的验证工作。

【问题讨论】:

  • 例子会更好。
  • 如其所言,您似乎只需要在/foo/.test("bar")!/foo/.test("bar") 之间进行交换...您能否更具体一些,也许可以发布一些示例代码?
  • 如果否定插入符号 (^) 的作用与您想要的相反,为什么不删除它呢?我假设您正在尝试删除标点符号?
  • 改用inputElement.data('valRegexPattern')
  • 并不是每一个“随机正则表达式”都可以很容易地被否定,甚至可以用来“去除无效字符”。但是,对于像您这样的有效字符类的简单重复,这是微不足道的。

标签: javascript regex validation


【解决方案1】:

要查找无效字符,只需从您的正则表达式中删除^。 carret 是括号内所有内容的负数。

data-val-regex-pattern="[|<>:\?'\*\[\]\=%\$\+,;~&\{\}]*"

这将返回不需要的字符,以便您替换它们。

另外,由于你想去掉很多非单词字符,你可以尝试一个更简单的正则表达式。如果你只想要单词字符和空格,你可以使用这样的东西:

data-val-regex-pattern="[\W\S]*"

【讨论】:

  • 解释一下。 :) "插入符号 (^) 在方括号中表示否定匹配;因此,您选择了集合中的任何内容。"
  • 其实我正在尝试找到一个可以反转任何正则表达式的通用函数。属性中的表达式需要保留。
  • @Thijs:不幸的是,这是不可能的。 RegEx 没有通用的“反转”功能 - 特别是因为您所说的“反转”可以改变。
  • @Thijs,如果您经常执行此过程,也许您应该更改验证码。我认为这比必须“反转”正则表达式更简单。在您的验证中,您只需在发现任何无效字符时告诉输入无效。这比必须反转正则表达式要好,而且更不容易出错。
  • @MauricioMoraes:这是个好主意!我想我会走那条路。
【解决方案2】:

你的reges是这样的:

[^|<>:\?'\*\[\]\=%\$\+,;~&\{\}]*

也就是说,它多次匹配任何非无效字符。

然后你把它替换为空,所以你只留下坏字符。

试试这个,不要否定(帽子移到其他地方):

[|^<>:\?'\*\[\]\=%\$\+,;~&\{\}]*

【讨论】:

  • 我不想更改数据属性中的正则表达式。我正在尝试找到一个适用于多个正则表达式的通用 negateRegex(regex)
【解决方案3】:

以下答案是对否定正则表达式的一般问题。在您的特定情况下,您只需要否定一个字符组,或更准确地说,删除一个字符组的否定 - 这在其他答案中有详细说明。

常规语言——那些完全由匹配某个 RE 的字符串组成的语言——实际上在否定下是封闭的:is 另一个 RE 与原始 RE 不匹配的字符串完全匹配。然而,它的构造并非易事,这或许可以解释为什么 RE 实现通常不提供否定运算符。

然而,Javascript 正则表达式语言具有使其比常规语言更具表现力的扩展;尤其是负前瞻结构。

如果R1 是一个正则表达式,那么

^(?!.*(R1))

精确匹配不包含 R1 匹配项的字符串。

^(?!R1$)

精确匹配整个字符串与 R1 不匹配的字符串。

即。否定。

对于重写任何与给定正则表达式不匹配的子字符串,以上是不够的。一个人必须做类似的事情

((?!R1).)*

这将捕获任何不包含与R1 匹配的子字符串的子字符串。 - 但对边缘情况的考虑表明,这并不能完全达到我们所追求的效果。例如((?!ab).)*匹配“ab”中的“b”,因为“ab”不是“b”的子串。

一个人可以作弊,让你的正则表达式喜欢;

(.*)(R1|$)

并改写为T1$2

T1 是您要重写的目标字符串。

这应该将字符串中与R1 不匹配的任何部分重写为T1。但是,我会非常小心任何边缘情况。如此之多,以至于从头开始编写正则表达式可能比尝试通用方法更好。

【讨论】:

  • 如果我理解正确,这只适用于“不使用以下字符”类型的正则表达式?我试图找到适用于所有正则表达式的东西。感谢您展示消极的前瞻性,我不知道这种技术。
  • @Thijs 不,这是针对一般正则表达式(或者至少是没有前瞻/后视的正则表达式)。另请注意,我已经扩展了重写部分的答案。
  • @Thijs 但是请注意,它与否定正则表达式的含义无关。 ((?!R1).) 将完美匹配任何不包含与 R1 匹配的子字符串作为子字符串 - 问题是这几乎肯定不是我们所追求的。
  • Wikipedia 说“常规语言在..集合理论布尔运算下关闭时,你为什么说“常规语言在否定下不关闭”:联合......,交集......,和补充 ...”?如果您不这样做,我打算尝试澄清这一点,但也许您可以做得更好,知道您的意思。
  • 您真的需要删除整个答案吗?它是唯一一个试图做 OP 想要做的事情! (其他人只是说如何否定一个非常具体的 RE。)我原以为你可以修改你关于常规语言的陈述,例如它们在补码下是封闭的,但是 RE 实现经常扩展这个概念(这可能会破坏闭包属性),并且很少(从不?)提供明确的否定操作。可能还有一些关于 Javascript 实现的特定内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-02
  • 2011-07-09
相关资源
最近更新 更多