在正则表达式中,匹配一个或另一个,或两者

rha*_*ton 23 javascript regex

在正则表达式中,我需要知道如何匹配一个或另一个,或两者(按顺序).但至少有一件事需要存在.

例如,以下正则表达式

/^([0-9]+|\.[0-9]+)$/
Run Code Online (Sandbox Code Playgroud)

会匹配

234
Run Code Online (Sandbox Code Playgroud)

.56
Run Code Online (Sandbox Code Playgroud)

但不是

234.56
Run Code Online (Sandbox Code Playgroud)

而以下正则表达式

/^([0-9]+)?(\.[0-9]+)?$/
Run Code Online (Sandbox Code Playgroud)

将匹配上面的所有三个字符串,但它也将匹配我们不想要的空字符串.

我需要一些能匹配上面所有三个字符串的东西,但不是空字符串.有一个简单的方法吗?

更新:

安德鲁和贾斯汀的下面都是我提供的简化示例,但他们没有(除非我错了)为我希望解决的实际用例工作,所以我现在应该把它放进去.这是我正在使用的实际正则表达式:

/^\s*-?0*(?:[0-9]+|[0-9]{1,3}(?:,[0-9]{3})+)(?:\.[0-9]*)?(\s*|[A-Za-z_]*)*$/
Run Code Online (Sandbox Code Playgroud)

这将匹配

45
45.988
45,689
34,569,098,233
567,900.90
-9
-34 banana fries
0.56 points
Run Code Online (Sandbox Code Playgroud)

但它不会匹配

.56
Run Code Online (Sandbox Code Playgroud)

我需要它来做到这一点.

huo*_*uon 27

完全通用的方法,因为正则表达式/^A$//^B$/是:

/^(A|B|AB)$/
Run Code Online (Sandbox Code Playgroud)

/^([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/
Run Code Online (Sandbox Code Playgroud)

请注意,其他人已使用您的示例的结构进行简化.具体来说,他们(隐含)因式分解它,退出共同[0-9]*[0-9]+在左侧和右侧的因素.

为此工作的是:

  • 交替的所有元素都结束了[0-9]+,所以把它拉出来:/^(|\.|[0-9]+\.)[0-9]+$/
  • 现在我们有可能在交替中使用空字符串,因此使用?(即使用等价(|a|b) = (a|b)?)重写它:/^(\.|[0-9]+\.)?[0-9]+$/
  • 再次,使用公共后缀(\.此时)的替换:/^((|[0-9]+)\.)?[0-9]+$/
  • 模式(|a+)是相同的a*,所以,最后:/^([0-9]*\.)?[0-9]+$/


Kal*_*Kal 8

huon 的回答很好(还有一点令人费解的答案,直到最后)。对于任何正在寻找此问题标题“在正则表达式中,匹配一个或另一个或两者”的快速简单答案的人,值得一提的是,甚至(A|B|AB)可以简化为:

A|A?B
Run Code Online (Sandbox Code Playgroud)

如果 B 稍微复杂一点,那就很方便了。

现在,正如 c0d3rman 所观察到的,这本身永远不会与 AB 匹配。它只会匹配 A 和 B。(A|B|AB有同样的问题。)我遗漏的是原始问题的最重要的上下文,其中字符串的开头和结尾也被匹配。这是完整写出来的:

^(A|A?B)$
Run Code Online (Sandbox Code Playgroud)

更好的是,只需按照 c0d3rman 推荐的顺序切换顺序,就可以在任何地方使用它:

A?B|A
Run Code Online (Sandbox Code Playgroud)


And*_*nov 5

是的,您可以将所有这些与这样的表达式匹配:

/^[0-9]*\.?[0-9]+$/
Run Code Online (Sandbox Code Playgroud)

请注意,它也不匹配空字符串(您的最后一个条件)。