正则表达式价格匹配

时间:2014-02-25 15:07:25

标签: python regex python-2.7

我有一个刮擦价格的网络刮板,因为我需要它来查找字符串中的以下价格:

  • 762,50
  • 1.843,75

在我的第一次天真实施中,我没有接受。考虑并将第一个数字与此正则表达式完美匹配:

re.findall("\d+,\d+", string)[0]

现在我需要匹配两个案例,我最初的想法是:

re.findall("(\d+.\d+,\d+|\d+,\d+)", string)[0]

有了一个想法,使用或运算符,可以找到第一个或第二个,哪个不起作用,有任何建议吗?

7 个答案:

答案 0 :(得分:2)

在正则表达式中,dot(.)匹配任何字符(除了换行符,除非未设置DOTALL标志)。将其转义为与.字面匹配:

\d+\.\d+,\d+|\d+,\d+
   ^^

要匹配多个前导数字,正则表达式应为:

>>> re.findall(r'(?:\d+\.)*\d+,\d+', '1,23 1.843,75   123.456.762,50')
['1,23', '1.843,75', '123.456.762,50']

注意使用非捕获组,因为re.findall返回组列表如果模式中存在一个或多个组。

<强>更新

>>> re.findall(r'(?<![\d.])\d{1,3}(?:\.\d{3})*,\d+',
...            '1,23 1.843,75   123.456.762,50  1.2.3.4.5.6.789,123')
['1,23', '1.843,75', '123.456.762,50']

答案 1 :(得分:2)

无需使用或,只需将第一部分添加为可选参数:

(?:\d+\.)?\d+,\d+

?之后的(?:\d+\.)使其成为可选参数。 '?:'表示不捕获该组,只是匹配它。

>>> re.findall(r'(?:\d+\.)?\d+,\d+', '1.843,75 762,50')
['1.843,75', '762,50']

另请注意,您必须转义符合除换行符之外的任何字符的.(点)(请参阅http://docs.python.org/2/library/re.html#regular-expression-syntax

答案 2 :(得分:0)

通常,您有一组零或多个XXX.,后跟一个或多个XXX,,每个最多3个数字,后跟两个数字(始终)。你是否也想支持像1,375这样的数字(没有'分'?)。您还需要避免一些错误的检测案例。

看起来像这样:

matcher=r'((?:(?:(?:\d{1,3}\.)?(?:\d{3}.)*\d{3}\,)|(?:(?<![.0-9])\d{1,3},))\d\d)'

re.findall(matcher, '1.843,75     762,50')

这会检测到很多边界情况,但可能无法捕捉到所有内容......

答案 3 :(得分:0)

怎么样:

(\d+[,.]\d+(?:[.,]\d+)?)

匹配

- 一些数字后跟,或。和一些数字

- 一些数字后跟,或。和一些数字后跟,或。和一些数字

匹配:762,50和1.843,75和1,75

它也会匹配1.843.75你还好吗?

See it in action.

答案 4 :(得分:0)

我会用这个:

\d{1,3}(?:\.\d{3})*,\d\d

这将匹配点为千位分隔符的数字

答案 5 :(得分:0)

\d*\.?\d{3},\d{2}

See the working example here

答案 6 :(得分:0)

这可能比正则表达式慢,但鉴于您正在解析的字符串可能很短,这应该没关系。

由于下面的解决方案不使用正则表达式,因此它更简单,您可以更确定地找到有效的浮点数。此外,它将数字字符串解析为Python浮点数,这可能是您打算执行的下一步。

import locale
locale.setlocale(locale.LC_ALL, 'en_DK.UTF-8')

def float_filter(iterable):
    result = []
    for item in iterable:
        try:
            result.append(locale.atof(item))
        except ValueError:
            pass
    return result

text = 'The price is 762,50 kroner'

print(float_filter(text.split()))

产量

[762.5]

基本思路:通过设置丹麦语区域设置,locale.atof将逗号分析为小数点,将点分组为分组分隔符。

In [107]: import locale

In [108]: locale.setlocale(locale.LC_ALL, 'en_DK.UTF-8')
Out[108]: 'en_DK.UTF-8'

In [109]: locale.atof('762,50')
Out[109]: 762.5

In [110]: locale.atof('1.843,75')
Out[110]: 1843.75