0

我想为 python 片段创建一个正则表达式。

import re
pattern = "\d*\.?\d+[Ee]?[+-]?\d*"
r = re.compile(pattern)
txt = """
12
.12
12.5
12.5E4
12.5e4
12.4E+4
12E4
12e-4
"""
x = r.findall(txt)
print(x)

用于过滤来自 txt 的所有有效输入,此代码很好,但输入无效,例如

.12e, 12.3+4

也被允许我该如何解决这个问题?

4

8 回答 8

1

不需要时不要使用正则表达式。让 Python 确定哪些是有效的更符合 Pythonic[tm](并且更容易、更可靠)。

results = []
for line in txt.split():
    try:
        float(line)
    except ValueError:
        pass
    else:
        results.append(line)
print results
于 2012-10-23T20:26:07.920 回答
1

我建议你使用正则表达式模式

^(?=\.?\d)\d*(?:\.\d*)?(?:[eE][+-]?\d+)?$
于 2012-10-23T20:24:08.533 回答
1

传统的正则表达式是这样的:

pattern = (
    "(?:"
    r"\d+(?:\.\d+)(:?[Ee][-+]?\d+)"
    "|"
    r"\.\d+(:?[Ee][+-]?\d+)"
    ")"
)

但是你总是可以用简单的方法做事:

def is_number(x):
    try:
        float(x)
        return True
    except ValueError:
        return False
于 2012-10-23T20:17:21.730 回答
0

你可以试试:\d*\.?\d+(?:[Ee][+-]?\d+)?$。这将指数部分标记为一个组。我还添加了一个$以确保它与字符串的结尾匹配。

此外,由于您的正则表达式包含\,因此您应该使用原始字符串文字,例如:r'\n',它是文字\n,而不是换行符。

更简单的方法是使用float()并检查ValueError异常。

于 2012-10-23T20:14:39.827 回答
0

尝试将您的正则表达式更改为以下内容:

\d*\.?\d+(?:[Ee][+-]?\d+)?

这使得如果eorE存在,则始终至少有一个数字,因此+and-仅当它们跟随eor时才有效E

请注意,您应该使用原始字符串文字来确保正确转义反斜杠(特别不会影响此字符串,但如果您尝试\b在正则表达式中使用类似的东西,您会看到不同之处):

pattern = r"\d*\.?\d+(?:[Ee][+-]?\d+)?"
于 2012-10-23T20:14:52.543 回答
0

你在这里,可能是最简单的:

^(\d*\.?\d+([Ee][+-]?\d+)?)$

将 ^ 和 $ 替换为您想要的分隔符,空格或其他内容。

解决方案说明:

您的解决方案

\d*\.?\d+[Ee]?[+-]?\d*

允许 E 放置不带数字 -> 因此 \d+ 在我的末尾。我还制作了 E 和可选的 +/-,然后是单个组中的强制数字(即,将其全部括在括号中),因此它们不能没有彼此而存在。整个组 ([Ee][+-]?\d+) 是可选的 (?) 以适应没有该符号的数字示例。

于 2012-10-23T20:29:46.980 回答
0

或者,避免一起使用正则表达式,使用 Python 标记器来查找它们:

test2.txt

一些颠簸
2.34
1.7e2
一些颠簸

示例代码

from tokenize import generate_tokens, NUMBER

source = open('test2.txt').readline
numbers = [ (val, eval(val)) for typ, val, _, _, _ in generate_tokens(source) if typ==NUMBER]
print numbers
# [('2.34', 2.34), ('1.7e2', 170.0)]
于 2012-10-23T20:31:59.477 回答
0

这样的事情应该这样做(未经测试):

"\d*\.?\d+(?:[Ee][+-]\d)?\d*"
于 2012-10-23T20:19:04.837 回答