【问题标题】:How to extract only Numbers from the value $1,632.50 (BigQuery)如何从价值 $1,632.50 (BigQuery) 中仅提取数字
【发布时间】:2019-06-15 06:52:21
【问题描述】:

我想只提取小数点前的数字。

例如 -> $1,632.50

我希望它返回 1632。

如果存在与值关联的逗号,我当前的正则表达式 (r'[0-9]+') 不会获取正确的值。

示例 --> $1,632.50 它返回 1

但是对于 ---> $500.00 它返回 500 在这种情况下它工作正常

我是正则表达式的新手。任何帮助表示赞赏

PS:我目前正在使用 Bigquery 和 我只有 REGEX_EXTRACT 和 REGEX_REPLACE 可以使用。

这里的大多数解决方案都适用于普通的 python 脚本,但我仍然无法让它在 BigQuery 上运行

【问题讨论】:

  • 也许你可以不用正则表达式,使用str.replacestr.split
  • REPLACE((REGEXP_EXTRACT(amount , r'([\d,]+)')),',','') 这行得通。我想这里有更好的选择,但我现在可以接受
  • 您的声誉得分较低。对 SO 很重要 - 您可以使用已发布答案左侧投票下方的勾号 mark accepted answer。请参阅meta.stackexchange.com/questions/5234/… 了解为什么它很重要!对vote on answer 也很重要。投票选出有帮助的答案。您可以查看当有人回答您的问题时该怎么做 - stackoverflow.com/help/someone-answers。遵循这些简单的规则,您可以提高自己的声誉得分,同时让我们有动力回答您的问题 - 考虑一下!
  • @MikhailBerlyant 谢谢!我试图找出如何接受正确答案。我是新来的:)

标签: python sql regex google-bigquery


【解决方案1】:

在不使用正则表达式的 Python 中执行此操作的一种方法是提取位于美元符号和小数之间的字符串部分,然后使用 replace 删除其中的所有逗号。

s = "My price is: $1,632.50"
extracted = s[s.find('$')+1:s.find('.')].replace(',', '')
print(extracted)

这与正则表达式相同:

# Look for the first dollar sign, followed by any mix of digits and 
# commas, and stop when you've found (if any) character after that
# which isn't a comma or digit.  So both "$1,234.50!" and "$1,234!"
# for example should give back "1234".
result = re.search("(\$)([\d,]+)([^,\d]*)", s)
print(re.sub(',', '', result.group(2)))

re.sub 与使用字符串 .replace 没有太大区别,但从技术上讲,这是一种使用“仅”正则表达式的方法。

【讨论】:

  • 如果字符串没有像$500 这样的美分,s.find(".") 返回 -1。
  • OP 说“在小数点之前”,暗示它被假定在那里。如果字符串本身是“$500”,它仍然有效,因为无论如何数字都在末尾。
【解决方案2】:

这似乎工作得很好:r'(\d{,3})?[.,]?(\d{3})?'。测试一下:

import re
pattern = r'(\d{,3})?[.,]?(\d{3})?'
tests = ['1,234.50',
         '456.7',
         '12']
for t in tests:
    print(''.join([g for g in re.match(pattern, t).groups() if g is not None]))
# 1234
# 456
# 12

不幸的是,您遇到了重复分组的问题。 re 包似乎不支持重复子组捕获。在这些情况下,您可能应该使用字符串替换。

分解正则表达式:

pattern = """ (          # begin capture group
               \d{,3}    # up to three digits
              )          # end capture group
              ?          # zero or one of these first groups of digits
              [.,]?      # zero or one period or comma (not captured)
              (          # begin capture group inside of the non-capture group
               \d{3}     # exactly three digits
              )          # end capture group
              ?          # zero or one of these
          """

您可能可以稍微简化一下,但重要的是您捕获每组由可选逗号分隔的三个数字(对第一个数字进行不同的处理,因为它最多可以是三个)。要将它们放在一起,只需在示例代码中使用''.join([g for g in re.match(pattern, my_string).groups() if g is not None])

【讨论】:

    【解决方案3】:

    以下是 BigQuery 标准 SQL

    REGEXP_REPLACE(str, r'\..*|[^0-9]', '')   
    

    如您所见,这里只有一个 REGEXP_REPLACE 可以完成工作

    您可以使用下面的虚拟数据进行测试,玩弄它

    #standardSQL
    WITH t AS (
      SELECT '$1,632.50' AS str UNION ALL
      SELECT  '$500.00'
    )
    SELECT 
      str, 
      REGEXP_REPLACE(str, r'\..*|[^0-9]', '') AS extracted_number
    FROM t 
    

    结果

    Row str         extracted_number     
    1   $1,632.50   1632     
    2   $500.00     500  
    

    【讨论】:

      【解决方案4】:

      在 BigQuery 中,您可以结合使用这两个功能:

      select regexp_replace(regexp_extract(str, '[^.]+'), '[^0-9]', '')
      from (select '$1,632.50' as str) x
      

      【讨论】:

        【解决方案5】:

        您的正则表达式 [0-9]+ 匹配一个数字的 1 次以上,并且不会匹配逗号。它也没有考虑美元符号。

        您可以做的是匹配一个美元符号,捕获一组 1+ 位数字和一个匹配逗号和 1+ 位数字的可选部分。然后,从该组中将逗号替换为空字符串。

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

        解释

        • \$匹配$
        • (抓包组
          • \d+ 匹配 1+ 位
          • (?:,\d+)? 匹配逗号和 1+ 位的可选捕获组
        • )关闭捕获组

        Regex demo

        【讨论】:

          【解决方案6】:

          我认为最简单的解决方案就是使用re.sub

          例子:

          import re
          
          result = re.sub(r'[^\d.]', '', '$1,234.56')
          

          这将替换所有非数字和.,只留下包括小数在内的数字。

          【讨论】:

          • 但是这个例子为我返回“1234.56”,而不是“1234”。
          【解决方案7】:

          您的正则表达式匹配第一个 位数字。它以逗号停止。仅使用一个正则表达式似乎很难做到这一点。

          所以搜索数字逗号,然后使用str.replace将逗号替换为空,转换为整数:

          import re
          
          s = "$1,632.50"
          
          result = int(re.search("([\d,]+)",s).group(1).replace(",",""))
          

          (不适用于$.50,但您可以使用其他技巧,例如将$ 替换为$0,然后再开始确保$ 后面有一个0)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-11-12
            • 2019-09-26
            • 2014-05-29
            • 1970-01-01
            • 1970-01-01
            • 2021-01-08
            • 2022-10-08
            • 1970-01-01
            相关资源
            最近更新 更多