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

时间:2012-11-12 21:39:04

标签: javascript regex

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

例如,以下正则表达式

/^([0-9]+|\.[0-9]+)$/

将匹配

234

.56

但不是

234.56

以下正则表达式

/^([0-9]+)?(\.[0-9]+)?$/

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

我需要的东西能匹配上面所有三个字符串,但不是空字符串。有没有一种简单的方法可以做到这一点?

更新

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

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

这将匹配

45
45.988
45,689
34,569,098,233
567,900.90
-9
-34 banana fries
0.56 points

但它不匹配

.56

我需要这样做。

5 个答案:

答案 0 :(得分:25)

给定正则表达式/^A$//^B$/的完全通用方法是:

/^(A|B|AB)$/

/^([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/

请注意其他人已使用您的示例结构进行简化。具体来说,他们(隐含地)将其分解,以便在左侧和右侧拉出常见的[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]+$/

答案 1 :(得分:4)

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

/^[0-9]*\.?[0-9]+$/

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

答案 2 :(得分:4)

不确定。您需要可选的量词?

/^(?=.)([0-9]+)?(\.[0-9]+)?$/

以上内容略显笨拙,但我想向您展示一些?引入的确切模式。在此版本中,(?=.)确保它不接受空字符串因为我已经使这两个条款可选。一个更简单的版本是:

/^\d*\.?\d+$/

这满足您的要求,包括防止空字符串。

请注意,有很多方法可以表达这一点。有些很长,有些非常简洁,但是they become more complex depending on what you're trying to allow/disallow

编辑:

如果你想在一个更大的字符串中匹配它,我建议拆分并使用/^\d*\.?\d+$/测试结果。否则,您将冒险匹配aaa.123.456.bbb之类的内容或缺少匹配项(相信我,您会的.JavaScript缺乏外观支持确保可以打破我能想到的任何模式)。

如果你知道一个事实,你不会得到如上所述的字符串,你可以使用分词而不是^$锚点,但它会变得复杂,因为.之间没有单词分隔符和(空格)。

/(\b\d+|\B\.)?\d*\b/g

应该这样做。它会阻止aaa123.456bbb之类的内容,但会允许123456123.456。这将允许aaa.123.456.bbb,但正如我所说,如果你想全面处理它,你将需要两个步骤。

编辑2:您的用例

如果你想在开头允许空格,负面/正面标记和最后的单词,那些实际上是相当严格的规则。这是好事。您可以将它们添加到上面最简单的模式中:

/^\s*[-+]?\d*\.?\d+[a-z_\s]*$/i

允许成千上万的群体使事情变得复杂,我建议你看看我链接的答案。这是结果模式:

/^\s*[-+]?(\d+|\d{1,3}(,\d{3})*)?(\.\d+)?\b(\s[a-z_\s]*)?$/i

\b确保数字部分以数字结尾,后跟至少一个空格。

答案 3 :(得分:0)

也许这有助于(给你一般的想法):

(?:((?(digits).^|[A-Za-z]+)|(?<digits>\d+))){1,2}

此模式匹配字符后面的字符,数字或数字,但不匹配数字后面的字符。 模式匹配aa,aa11和11,但不匹配11aa,aa11aa或空字符串。 不要被&#34;。^&#34;感到困惑,这意味着&#34;一个字符后跟行开头&#34;,它旨在防止任何匹配。

请注意,这不适用于所有版本的正则表达式,您的正则表达式版本必须支持(?(named group)true|false)

答案 4 :(得分:0)

huon的回答很不错(还有一些脑筋急转弯直到最后)。对于希望快速,简单地回答此问题的标题的人,“在正则表达式中,匹配一件事或另一件事,或者两者都匹配”,值得一提的是,甚至(A | B | AB )可以简化为:

A|A?B

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