33

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

例如下面的正则表达式

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

将匹配

234

.56

但不是

234.56

而下面的正则表达式

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

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

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

更新:

下面的 Andrew 和 Justin 都适用于我提供的简化示例,但它们(除非我弄错了)不适用于我希望解决的实际用例,所以我现在应该把它放进去。这是我正在使用的实际正则表达式:

/^\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

我需要它来做到这一点。

4

5 回答 5

38

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

/^(A|B|AB)$/

IE

/^([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]+$/
于 2012-11-12T21:45:10.850 回答
6

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

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

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

于 2012-11-12T21:42:01.687 回答
4

当然。您需要可选的量词?.

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

上面看起来有点尴尬,但我想向你展示你的确切模式,其中包含一些?s。在这个版本中,(?=.)确保它不接受空字符串,因为我已经将这两个子句都设为可选。一个更简单的版本是这样的:

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

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

请注意,有很多方法可以表达这一点。有些很长,有些非常简洁,但根据您尝试允许/禁止的内容,它们会变得更加复杂

编辑:

如果您想在更大的字符串中匹配它,我建议使用/^\d*\.?\d+$/. 否则,您将面临匹配aaa.123.456.bbb或丢失匹配的风险(相信我,您会的。JavaScript 缺乏后向支持确保可以打破我能想到的任何模式)。

如果你知道你不会得到像上面这样的字符串,你可以使用分词而不是^$锚点,但它会变得复杂,因为. (空格)之间没有分词。

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

那应该这样做。它会阻止类似的东西aaa123.456bbb,但它会允许123,456123.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数字结尾,并且后跟至少一个空格。

于 2012-11-12T21:42:42.900 回答
4

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

A|A?B

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

于 2019-03-07T05:27:25.507 回答
0

也许这有帮助(给你一个大致的想法):

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

此模式匹配字符、数字或字符后面的数字,但不匹配数字后面的字符。该模式匹配 aa、aa11 和 11,但不匹配 11aa、aa11aa 或空字符串。不要对“.^”感到困惑,它的意思是“一个字符后跟行开始”,它的目的是完全阻止任何匹配。

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

于 2016-05-01T12:34:17.197 回答