只匹配数字和连字符的正则表达式

4

我正在尝试理解正则表达式,在处理长度为10的数字时,我只需要进行如下操作:

/^[0-9]{10}$/

仅针对连字符,我可以做到

/^[-]$/

使用组合表达式将两者结合在一起将导致
/^([0-9]{10})|([-])$/

这个表达式并没有按照预期工作,如果字符串无效,它会匹配部分字符串而不是完全不匹配。

enter image description here

如何创建只接受"-"或10位数字的正则表达式?


2
a|b 是一个替代项:匹配 ab。 在这里,你的a模式是^([0-9]{10}),而你的b模式是([-])$。 添加括号将选项限制为不包括 ^$ - Ry-
如果您在regxp101屏幕右侧查看了“解释”,它会提供一些很好的线索。 - user663031
4个回答

5

你可以将你的两个正则表达式精确地组合起来,这样就可以正常工作。换句话说,只需使用交替/管道操作符进行组合即可。

/^[0-9]{10}$/

and

/^[-]$/

就像原样,直接进入
/^[0-9]{10}$|^[-]$/
 ↑↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑     YOUR ORIGINAL REGEXPS, COMBINED AS IS WITH |

这可以表示为:

正则表达式可视化

这样就可以了。正如其他人指出的那样,你不需要在字符类中指定连字符。
/^[0-9]{10}$|^-$/
              ↑        SIMPLIFY [-] TO JUST -

现在,我们注意到这两种替代方案都以^开头和$结尾。这有点重复,也使得很难立即看出正则表达式总是从开头匹配到结尾。因此,我们可以按照其他答案中所解释的方法,将^$从两个子正则表达式中取出,并使用分组运算符()组合它们的内容:
/^([0-9]{10}|-)$/
  ↑↑↑↑↑↑↑↑↑↑↑↑↑        GROUP REGEXP CONTENTS WITH PARENS, WITH ANCHORS OUTSIDE

相应的可视化结果如下所示:

正则表达式可视化

虽然以上也可以正常工作,但你也可以使用 \d 替代 [0-9],这样最终的、最简单的版本就是:

/^(\d{10}|-)$/
   ↑↑                  USE \d FOR DIGITS

这个可以用可视化来表示:

正则表达式可视化

如果由于某些原因您不想“捕获”该组,请使用(?:,例如

/^(?:\d{10}|-)$/
   ↑↑                  DON'T CAPTURE THE GROUP

现在的可视化展示了该组未被捕获:

正则表达式可视化

顺便提一下,在您原始尝试将两个正则表达式组合时,我注意到您将它们加以括号表示,如下:

/^([0-9]{10})|([-])$/
  ↑↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑    YOU PARENTHESIZED THE SUB-REGEXPS

实际上这并不是必要的,因为管道(或选择)操作符已经具有很低的优先级(实际上它是任何正则表达式操作符中优先级最低的);"低优先级"意味着它只会在两侧的内容已经处理完后才会应用,所以你在这里写的与下面的相同:

/^[0-9]{10}|[-]$/

然而,从其可视化效果可以看出,对于其他回答中提到的原因,它仍然无法正常工作:

正则表达式可视化


1
非常感谢您提供如此详细的解释!感谢您抽出时间画出这个图表。这让我更好地理解了正则表达式!谢谢! - Zanko
嘿,我在哪里可以制作像那样的正则表达式图形? - beppe9000

3
如何创建一个仅接受“-”或10位数字的正则表达式?
您可以使用以下代码:
/^([0-9]{10}|-)$/

正则表达式演示

你的正则表达式中的括号放错位置了,只是断言最后有连字符存在。

以下是 OP 正则表达式的有效分解:

^([0-9]{10})   # matches 10 digits at start
|              # OR
([-])$         # matches hyphen at end

这将导致 OP 的正则表达式匹配任何以 10 个数字开头或以连字符结尾的输入,使这些无效输入也成为有效匹配。
1234567890111
1234----
------------------
1234567890--------

2
我觉得 OP 想要一个单独的 '-'。不确定……不太清楚……但根据 /^[-]$/,我相信这是他想要的。 - pah
1
谢谢,这很完美!虽然我不确定是什么区别使得这个例子能够工作!正则表达式很令人困惑。 - Zanko
@Zanko:我在我的回答中进一步解释了为什么你的正则表达式失败了。如果你还有任何疑问,请告诉我。 - anubhava

2
为了得到一个只接受“-”或者10位数字的正则表达式 - 请按照下面所示更改您的正则表达式:
^(\d{10}|-)$

DEMO link


谢谢,这也有效。我仍然对括号的目的感到困惑。 - Zanko

1
您的正则表达式问题在于它要么寻找以10个数字开头的字符串,即^([0-9]{10}),要么以“-”结尾,即([-])$。您需要添加额外的包装^( .. )$才能使其起作用。例如:
/^(([0-9]{10})|([-]))$/

更好的做法是使用正则表达式/^([0-9]{10}|-)$/,因为[-]-是相同的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接