使用正则表达式删除包含数字的双引号

时间:2018-02-03 18:15:41

标签: python regex

我使用以下字符串:

'"name": "Gnosis", \n        "symbol": "GNO", \n        "rank": "99", \n        "price_usd": "175.029", \n        "price_btc": "0.0186887", \n        "24h_volume_usd": "753877.0"'

我必须在python中使用re.sub()来仅替换包含数字的双引号("),以便稍后在JSON中解析它。我试过一些正则表达式,但没有成功。这是我最好的尝试:

exp = re.compile(r': (")\D+\.*\D*(")', re.MULTILINE)
response = re.sub(exp, "", string)

我经常搜索类似的问题,但没有找到另一个类似的问题。

编辑:

最后我使用了(感谢S. Kablar):

fomatted = re.sub(r'"(-*\d+(?:\.\d+)?)"', r"\1", string)
parsed = json.loads(formatted)

问题是this endpoint将格式错误的字符串作为JSON返回。

其他用户answered"首先用json解析字符串,然后将数字转换为float"使用for循环,我认为,这是一种非常有效的方法,你也将被迫在你的响应中选择int或float类型。为了避免疑问,我写了this gist,在那里我向您展示了不同方法与基准测试之间的比较,现在我在这种情况下会信赖正则表达式。

感谢大家的帮助

3 个答案:

答案 0 :(得分:2)

首先用json解析字符串,然后将数字转换为浮点数:

string = '{"name": "Gnosis", \n        "symbol": "GNO", \n        "rank": "99", \n        "price_usd": "175.029", \n        "price_btc": "0.0186887", \n        "24h_volume_usd": "753877.0"}'

data = json.loads(string)
response = {}
for key, value in data.items():
    try:
        value = int(value) if value.strip().isdigit() else float(value)
    except ValueError:
        pass
    response[key] = value

答案 1 :(得分:1)

正则表达式"(-?\d+(?:[\.,]\d+)?)" 替换\1

详细说明:

  • ()捕获小组
  • (?:)非捕获组
  • \d匹配一个数字(等于[0-9]
  • +匹配一次且无限次
  • ?匹配0到1次
  • \1第1组。

Python代码

def remove_quotes(text):
    return re.sub(r"\"(-?\d+(?:[\.,]\d+)?)\"", r'\1', text)

remove_quotes('"percent_change_7d": "-23.43"') >> "percent_change_7d": -23.43

答案 2 :(得分:1)

你走近了。你想保存数字和冒号,所以你需要把它们放在括号中,而不是其余的。此外,数字为\d,而不是\D不是 - 数字)。

所以:

exp = re.compile(r'(: *)"(\d+\.?\d*)"', re.MULTILINE)
response = re.sub(exp, "\\1\\2", string)

\d+\.?\d*  means "a number (or more), a point (or not), any numbers"

边境案例

上述内容不包括“.125”,即数字,一个点。

如果你改为“\ d *。?\ d *”,那就匹配“。”,因为它是**任何数字“,一点,任何数字”。

我认为唯一可行的方法是

 (\d+\.?\d*|\.\d+)

与|意思是“或”:所以,一个数字可选地后跟一个点和任何数字(这匹配“17.”),一个点后跟至少一个数字。不幸的是,“\ d +。?\ d +”与“5”不匹配。

或者您指定所有三种情况:

 (\d+|\d+\.?\d+|\.\d+)

第一个整数(\ d +),然后是带或不带小数的浮点数,然后是单独的小数部分,不带前导零。