2

我正在寻找考虑指数的非十进制整数的正则表达式,老实说,在问这里之前我已经尝试了很多。

正则表达式应该

  • 匹配1.23E4,1.2334576E34122E3,123,456_
  • 不匹配1.234E2(因为它扩展为123.4)。
  • 不应该匹配1.22等等。

我的尝试是

^[+-]?([0-9]*\\.?[0-9]+|[0-9]+\\.?[0-9]*)([eE][+]?[0-9]+)?$

但是,正如您所看到的,我没有计算指数,因此在展开后我应该能够知道展开后的值 X 不包含小数。

有没有办法提取小数点后的位数.并将其与指数进行比较,以便我可以确定扩展后它不会包含小数点。

对于信息,只有可以在运行时工作的正则表达式对我有用。

请大家帮帮我...

4

2 回答 2

0

好的,所以只有当你真的需要这个来进行一些奇怪的正则表达式验证时。它是用 python 3 编写的,它没有试图变得紧凑(除了 python 中的正则表达式大小的可用内存之外,没有任何限制)。

def over(n):
    '''make aregexp for an exponent of n or more'''
    assert n < 100
    return r'([1-9]\d{2,}|%s)' % '|'.join(str(i) for i in range(n, 100))

def make_decimal(n_digits, n_decimal):
    '''make a regexp for a number with an "E" with the given number of significant digits and decimal places'''
    assert n_decimal < n_digits
    assert 100 > n_decimal >= 0
    if n_decimal:
        return r'\d{%d}.\d{%d}E%s' % (n_digits-n_decimal, n_decimal, over(n_decimal))
    else:
        return r'\d{%d}E\d+'

def make_e(n_digits):
    '''make a regexp for an integer with an "E" with the given number of significant digits'''
    return '|'.join(make_decimal(n_digits, i) for i in range(n_digits))

def make_regexp(max_digits):
    '''make a regexp for a decimal integer with up to the given number of significant digits'''
    assert max_digits < 100
    return r'(\d+|%s)' % '|'.join(make_e(i) for i in range(max_digits+1))

这是一些测试代码。

from re import compile

rx = make_regexp(8)
m = compile('^%s$' % rx)
for n in ['1.23E4', '1.2334576E34', '122E3', '123', '456']:
    assert m.match(n), n
for n in ['1.234E2', '1.22']:
    assert not m.match(n), n

对于最多 8 位有效数字(在 E 的左侧),这似乎是一个合理的限制,生成的正则表达式是 8774 位长。您可以显着减少这种情况(例如,请参阅https://stackoverflow.com/a/17840228/181772),但是需要什么(正则表达式引擎能够从中生成更小的内部自动机)?

于 2013-07-30T00:47:56.793 回答
0

描述

这不是不可能,而是相当困难,而且这种表达方式真的会开始失控。以这个 2831 字符的怪物为例:

  • 用指数验证一个数字将扩展为一个整数
  • 需要一个数字123.456e78901234.678e1,234,567
  • 如果指数包含逗号,它们必须出现在正确的逗号分隔的三位数分组中
  • 仅支持小数点后最多 99 位的数字

正如这里所写,它确实需要使用x忽略空格和注释的选项。[eE]通过替换withe和使用i选项,表达式可以缩短到大约 2041 ;但是,这会稍微降低性能,因为[0-9]类包含所有 unicode 字符而不仅仅是 0-9。\d\d

^
(?=.*?[eE][0-9]{1,3}(?:,[0-9]{3})*|[0-9]*$)  # validate commas are in the correct order
(?=[0-9]+\.   # match the integer portion of a real number
(?=
[0-9]{1,99}[eE][1-9](?:,?[0-9]){2,}

|[0-9]{1,9}[eE][1-9],?[0-9]
|[0-9]{10,19}[eE][2-9],?[0-9]
|[0-9]{20,29}[eE][3-9],?[0-9]
|[0-9]{30,39}[eE][4-9],?[0-9]
|[0-9]{40,49}[eE][5-9],?[0-9]
|[0-9]{50,59}[eE][6-9],?[0-9]
|[0-9]{60,69}[eE][7-9],?[0-9]
|[0-9]{70,79}[eE][89],?[0-9]
|[0-9]{80,89}[eE][9],?[0-9]
|[0-9]{90,99}[eE][1-9],?[0-9]

|(?=[0-9]{90}(?=.*?[eE]9)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{80}(?=.*?[eE]8)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{70}(?=.*?[eE]7)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{60}(?=.*?[eE]6)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{50}(?=.*?[eE]5)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{40}(?=.*?[eE]4)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{30}(?=.*?[eE]3)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{20}(?=.*?[eE]2)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))
|(?=[0-9]{10}(?=.*?[eE]1)(?:[eE].,?[0-9]|[0-9]{1}[eE].,?[1-9]|[0-9]{2}[eE].,?[2-9]|[0-9]{3}[eE].,?[3-9]|[0-9]{4}[eE].,?[4-9]|[0-9]{5}[eE].,?[5-9]|[0-9]{6}[eE].,?[6-9]|[0-9]{7}[eE].,?[7-9]|[0-9]{8}[eE].,?[89]|[0-9]{9}[eE].,?9))

|(?:[eE][0-9]|[0-9]{1}[eE][1-9]|[0-9]{2}[eE][2-9]|[0-9]{3}[eE][3-9]|[0-9]{4}[eE][4-9]|[0-9]{5}[eE][5-9]|[0-9]{6}[eE][6-9]|[0-9]{7}[eE][7-9]|[0-9]{8}[eE][89]|[0-9]{9}[eE]9)
)
|(?=[0-9]+[eE])   # integers
)
[+-]?
([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)
[eE][+]?((?:,?[0-9]+)+)

如此处所写,表达式使用忽略空格的 x 选项

例子

示例文本

1.2334576E34
1.23E4
1.2334576E34
122E3,123,456
1.234
1.234E2

火柴

[0] => 1.2334576E34
[1] => 1.23E4
[2] => 1.2334576E34
[3] => 122E3,123,456

在此处输入图像描述

于 2013-07-30T19:12:57.970 回答