【问题标题】:Remove digits from string python从字符串python中删除数字
【发布时间】:2018-08-23 18:03:45
【问题描述】:

我想从字符串中删除字典中给出的数字以外的所有数字。我已经编写了代码来删除它 但没有得到预期的结果。请看下面:

mystr=" hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the ip address 122521587502. This string tells about deleting digits 502 600 765 from this."

myDict={'600','700'} # set()

# snippet to remove digits from string other than digits given in the myDict 

我的解决方案

for w in myDict:
    for x in mystr.split():
        if (x.isdigit()):
            if(x != w):
                mystr.replace(x," ")

预期结果:

mystr=" hey I want to delete all the digits ex 600 700 m  given in this string. And getting request from the  
ip address . This string tells about deleting digits  600  from this."

【问题讨论】:

  • 你的字典是一套吗?
  • @BallpointBen,是的。谢谢,我会编辑问题。
  • 这不是字典而是集合,您可以使用in 运算符检查成员资格,而不是循环遍历集合。此外,永远不要更改您正在循环的迭代器。

标签: python string python-3.x for-loop


【解决方案1】:

这是一种方法。

例如:

import string

mystr= "hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the  ip address 122521587502. This string tells about deleting digits 502 600 765 from this."
mySet={'600','700'}

rep = lambda x: x if x in mySet else None
print( " ".join(filter(None, [rep(i) if i.strip(string.punctuation).isdigit() else i for i in mystr.split()])) )

输出:

hey I want to delete all the digits ex 600 700 m given in this string. And getting request from the ip address This string tells about deleting digits 600 from this.

【讨论】:

  • 检查你的输出
  • 谢谢..编辑答案。
【解决方案2】:

这是另一种选择。它会在点上添加空格,但也会删除ip address 之后的数字。由于数字后面的点,其他解决方案中没有这样做。

import re

mystr= "hey I want to delete all the digits ex 600 502 700 m 8745 given in this 
    string. And getting request from the  ip address 122521587502. This string 
    tells about deleting digits 502 600 765 from this."

myDict={'600','700'}

print(" ".join("" if (i.isdigit() and i not in myDict) \
    else i for i in re.findall(r'(?:\w+|\d+|\S)', mystr)))

输出:

hey I want to delete all the digits ex 600  700 m  given in this string . And 
getting request from the ip address  . This string tells about deleting digits  
600  from this .

PS: 修复点的空间有一个糟糕的选择:

print("".join("" if (i.isdigit() and i not in myDict) \
    else i if i == '.' or i == ',' \
    else ''.join([' ', i]) for i in re.findall(r'(?:\w+|\d+|\S)', mystr))
    .strip())

产生输出:

hey I want to delete all the digits ex 600 700 m given in this string. And 
getting request from the ip address. This string tells about deleting digits 
600 from this.

【讨论】:

  • 谢谢!!这个解决方案也很有效。一个快速的问题,是否可以添加对字母数字值的检查?如果字符串中存在字母数字值,则删除该值。
  • 当然。不过它会变成一个功能怪物……"".join("" if (i.isdigit() and i not in myDict) or re.search(r'^(?=.*[a-zA-Z])(?=.*[0-9])', i) else i if i == '.' or i == ',' else ''.join([' ', i]) for i in re.findall(r'(?:\w+|\d+|\S)', mystr)).strip()
  • 您可能想使用@Bear Brown 的解决方案...代码组织得更好(而且速度更快)...
  • 嘿,谢谢!但是这段代码已经删除了 myDict 中的数字。
  • 所以你根本没有得到任何号码?因为我在尝试时得到了正确的输出
【解决方案3】:
In [1]: mystr=" hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the ip address
   ...:  122521587502. This string tells about deleting digits 502 600 765 from this."
   ...: myDict={'600','700'}

首先您可以准备要删除的数据:

   ...: mystr_l = mystr.replace('.', "").split()
   ...: to_remove = sorted(list({x for x in set(mystr_l) if x.isdigit() and x not in myDict}))
   ...: 
   ...: print(to_remove)
['122521587502', '502', '765', '8745']

并将其从您的字符串中删除:

In [4]: for x in to_remove:
   ...:     mystr = mystr.replace(x, " ")
   ...:  

我的结果是:

In [6]: print(mystr)
嘿,我想删除此字符串中给出的所有数字 ex 600 700 m。
并从 ip 地址获取请求。该字符串表示从中删除数字 600。

还有一些性能测试:

def replace_digits(src_string, exclude_list):
    result = src_string
    string_l = src_string.replace('.', "").split()
    to_remove = sorted(list({x for x in set(string_l) if x.isdigit() and x not in exclude_list}))
    for x in to_remove:
        result = result.replace(x, "")
    return result

import re

def reg(src_string, exclude_list):
    return " ".join("" if (i.isdigit() and i not in exclude_list) \
                    else i for i in re.findall(r'(?:\w+|\d+|\S)', src_string))

测试:

In [8]: %timeit replace_digits(mystr, mySet)
11.3 µs ± 31.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [9]: %timeit reg(mystr, mySet)
    ...: 
25.1 µs ± 21.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

【讨论】:

    【解决方案4】:

    您可以使用这样的简单代码,只需要布尔逻辑和字符串操作的基本功能。

    mystr= "hey I want to delete all the digits ex 600 502 700 m 8745 given in this string. And getting request from the  ip address 122521587502. This string tells about deleting digits 502 600 765 from this."
    myDict={'600','700'}
    
    print( " ".join(c if not(bool(c.isdigit()) ^ bool(c in myDict)) else "" for c in mystr.split()) )
    

    但是这样做的问题是,这不会考虑带有句号或其他特殊字符的边缘数字,例如上面示例中的122521587502.。因此,如果您仍然需要考虑那些您可以使用带有正则表达式模式匹配的自定义函数而不是 isdigit() 并编写一些复杂的代码以获得所需的结果。下面是一个考虑数字以句号和逗号结尾的示例。

    ^[0-9]*[\,\.]?$ 可以用作正则表达式模式来匹配上述场景。 (您可以使用this 工具轻松调试正则表达式模式)。所以sn-p的代码如下:

    import re
    
    isNum = lambda c: True if re.match("^[0-9]*[\,\.]?$",c) else False
    func = lambda c: True if re.compile("[\,\.]").split(c) in myDict else False
    
    print(" ".join(c if not(isNum(c) ^ func(c)) else "" for c in mystr.split()))
    

    【讨论】:

      【解决方案5】:

      您可以使用re.sub 执行此操作。匹配任何数字并使用可调用的替换器仅过滤掉不需要的数字。

      使用set 存储您想要保留的数字序列,然后在遍历字符串时允许O(1) 查找。

      代码

      import re
      
      def remove_numbers(s, keep=None):
          if keep:
              keep = set(str(x) for x in keep)
              return re.sub(r'\b\d+\b', lambda m: m.group() if m.group() in keep else '', s)
          else:
              # Shortcircuit the use of a set if there is no sequence to keep
              return re.sub(r'\b\d+\b', '', s)
      

      示例

      allowed = {600, 700}
      s = 'I want to delete this: 100 200. But keep this: 600 700'
      print(remove_numbers(s, allowed))
      

      输出

      I want to delete this:  . But keep this: 600 700
      

      【讨论】:

        【解决方案6】:

        这显示了用于预处理和删除数字的组合算法。该程序还处理 122521587502. 边缘情况和 12.5 浮点值(如果它们恰好在输入字符串中)

        代码

        exclude_set = {'600', '700'}
        
        mystr=' hey I want to delete all the digits ex 600 502 700 8745 given in this string. And getting request from the ip address 122521587502. 12.5 This string tells about deleting digits 502 600 765 from this.'
        
        # Pre-process the string converting all whitespaces to single spaces
        mystr = " ".join(mystr.split())
        
        # Check if the word is both a digit and to be excluded
        # Also catch any floats and full-stops
        mystr_list = mystr.split()
        for word in mystr_list:
          if word.replace('.', '').isdigit() and word not in exclude_set:
            # Replace word or remove digit
            if word.endswith('.'):
              mystr_list[mystr_list.index(word)] = '.'
            else:
              mystr_list.remove(word)
        
        # Combine the list to form your string
        mystr = ' '.join(mystr_list)
        print (mystr)
        

        【讨论】:

          【解决方案7】:

          你不需要让自己复杂化。只需通过执行dict(zip(mySet, mySet)) 确保mySet 是一个字典,然后使用它来替换:

          import re
          mySet1 =dict(zip(mySet, mySet))
          
          re.sub("\\d+", lambda x:mySet1.get(x.group()), mystr)
          
          Out[604]: 'hey I want to delete all the digits ex 600  700 m  given in this string.
                     And getting request from the  ip address . This string tells about 
                     deleting digits  600  from this.'
          

          【讨论】:

            猜你喜欢
            • 2020-08-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-05
            • 1970-01-01
            相关资源
            最近更新 更多