考虑指数的非十进制整数的正则表达式

时间:2013-07-29 17:10:59

标签: regex

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

正则表达式

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

我的尝试是

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

然而,你可以看到我没有计算指数,所以在扩展后我应该能够告诉扩展后的值X不包含小数。

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

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

请帮帮我们......

2 个答案:

答案 0 :(得分: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),但是需要什么(正则表达式引擎能够从中生成一个小得多的内部自动机)?

答案 1 :(得分:0)

描述

这不是不可能的,但相当困难,表达式真的会开始失控。拿这个2831角色的怪物:

  • 验证带有指数的数字将扩展为整数
  • 要求号码位于123.456e78901234.678e1,234,567
  • 如果指数包含逗号,则它们必须以正确的逗号分隔的三位数分组显示
  • 仅支持小数点后最多99个位置的数字

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

^
(?=.*?[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

enter image description here