【问题标题】:Regular Expression(Ruby): match non-word, but exclude spaces正则表达式(Ruby):匹配非单词,但排除空格
【发布时间】:2014-05-12 13:12:22
【问题描述】:

^(?=(.*\d){4,})(?=(.*[A-Z]){3})(?!\s)(?=.*\W{2,})(?=(.*[a-z]){2,}).{12,14}$

上面的正则表达式试图:

  • 至少匹配 4 位数字 - (?=(.*\d){4,})
  • 完全匹配 3 个大写字母 - (?=(.*[A-Z]){3})
  • 不匹配空格 - (?!\s)
  • 至少匹配 2 个非单词字符 - (?=.*\W{2,})
  • 至少匹配 2 个较低的 - (?=(.*[a-z]){2,})
  • 字符串长度必须在 12 到 14 之间 - .{12,14}

但我在避免匹配空格方面遇到了挑战。似乎因为 \W 还包含空格,所以我之前对空格的否定前瞻被忽略了。

例如:

  • b4A@Ac33*8Pd -- 应该匹配
  • b4A@Ac3 3*8Pd -- 不应该匹配

rubular link

已编辑以提供进一步说明:

基本上,我试图避免拼写 POSIX [:punct:] 类中的所有字符,即 !"#$%&'()*+,./:;<=>?@\^_\{|}~-` .. 这就是我需要使用 \W 的原因。 . 但我也想排除空格

我可以用第二双眼睛,在这里更有经验的建议..

再次编辑,以纠正子模式中指定的计数混淆,如下面接受的答案中所指出的。

【问题讨论】:

  • 您能否添加一个应该匹配但不匹配的测试,或者添加一个不应该匹配但匹配的文本?
  • 我和@UriAgassi 在一起 - 它让提问者的生活更轻松
  • 我认为您的问题不在于\W,而在于.* - 删除(?=.*\W{1,}) 并查看...
  • 你的rubular链接错了吗?你说的是\W{1,},而rubular链接正则表达式是\W{1},还有其他区别
  • 在我看来(?!\s) 不起作用:rubular.com/r/e8cEKt3cEn 我不知道为什么,它应该对我来说......你可以尝试要求一个不包括空格的正则表达式

标签: ruby regex regex-negation


【解决方案1】:

不要使用点.,而是使用非空格\S

^(?=(.*\d){3,})(?=(.*[A-Z]){2})(?=.*\W{1,})(?=(.*[a-z]){1,})\S{12,14}$
//                                                  here ___^^

这是一个错字match at least 4 digits - (?=(.*\d){3,}), 应该是:

match at least 3 digits - (?=(.*\d){3,})

match at least 4 digits - (?=(.*\d){4,})

其他计数相同。

【讨论】:

  • 是的,错别字和混淆。基本上,我正在为不同的事情使用不同的模式,并且把计数都搞混了,但概念/想法是一样的。您最后匹配非空格的建议肯定有效.. 我还发现在我的原始模式中从 (?!\s) 更改为 (?!.* .*) 有效。
  • 一般来说,字符类的使用似乎会混淆 ruby​​ \W{n} 似乎在计算看不见的换行符 '\n'字符串的结尾
  • 我仍然很难理解为什么在我的原始模式中从 (?\s) 更改为 (?!.* .*) 有效,但 (?!.*\s.*) 的工作方式不同
  • @ChuxUzoeto: (?!\s) 不起作用,因为它在第一个位置搜索非空格,这就是 (?!.* .*) 起作用的原因。对我来说(?!.*\s.*) 也可以。
  • 我确实将子模式 (?!\s) 移动到了 .. 周围,甚至在第一个位置进行了测试(参见 rubular-1)。我再次针对(?!.*\s.*) 进行了测试,但它仍然无法匹配任何一个字符串(请参阅rubular-2).. 而(?!.* .*) 做正确的事情并匹配第一个字符串。奇怪而出人意料。
猜你喜欢
  • 2017-11-15
  • 1970-01-01
  • 2013-07-09
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 2017-12-24
  • 1970-01-01
相关资源
最近更新 更多