【问题标题】:Using regEx to remove digits from string使用正则表达式从字符串中删除数字
【发布时间】:2016-10-21 13:48:04
【问题描述】:

我正在尝试从字符串中删除所有未附加到单词的数字。例子:

 "python 3" => "python"
 "python3" => "python3"
 "1something" => "1something"
 "2" => ""
 "434" => ""
 "python 35" => "python"
 "1 " => ""
 " 232" => ""

到目前为止,我使用的是以下正则表达式:

((?<=[ ])[0-9]+(?=[ ])|(?<=[ ])[0-9]+|^[0-9]$)

它可以正确地做上面的一些例子,但不是全部。有什么帮助和解释吗?

【问题讨论】:

  • 等等,为什么"1something" => "something"
  • 谢谢,你是对的!更正它。
  • 为什么不直接搜索 ( \d+ ) 并删除它?
  • 因为它会删除附加的数字。
  • 我在不使用 reg exp 的情况下管理了一个解决方案。但我想看看 reg exp 解决方案。

标签: python regex


【解决方案1】:

为什么不只使用单词边界?

\b\d+\b

这是一个例子:

>>> import re
>>> words = ['python 3', 'python3', '1something', '2', '434', 'python 35', '1 ', ' 232']
>>> for word in words:
...     print("'{}' => '{}'".format(word, re.sub(r'\b\d+\b', '', word)))
...
'python 3' => 'python '
'python3' => 'python3'
'1something' => '1something'
'2' => ''
'434' => ''
'python 35' => 'python '
'1 ' => ' '
' 232' => ' '

请注意,这不会删除前后的空格。我建议使用strip(),但如果不是,您可以使用\b\d+\b\s*(后面的空格)或类似的东西。

【讨论】:

  • 只是一个警告,我认为,\b\d+\b,如果你有类似“python-3”或“python_3”的东西,这可能是你想要的,但它值得注意。
  • @milo.farrell 是 -,但不是下划线。
【解决方案2】:

您可以只拆分单词并删除任何更容易阅读的数字单词:

new = " ".join([w for w in s.split() if not w.isdigit()])

而且似乎更快:

In [27]: p = re.compile(r'\b\d+\b')

In [28]: s =  " ".join(['python 3', 'python3', '1something', '2', '434', 'python
    ...:  35', '1 ', ' 232'])

In [29]: timeit " ".join([w for w in s.split() if not w.isdigit()])

100000 loops, best of 3: 1.54 µs per loop

In [30]: timeit p.sub('', s)

100000 loops, best of 3: 3.34 µs per loop

它还会像您预期的输出一样删除空格:

In [39]:  re.sub(r'\b\d+\b', '', " 2")
Out[39]: ' '

In [40]:  " ".join([w for w in " 2".split() if not w.isdigit()])
Out[40]: ''

In [41]:  re.sub(r'\b\d+\b', '', s)
Out[41]: 'python  python3 1something   python     '

In [42]:  " ".join([w for w in s.split() if not w.isdigit()])
Out[42]: 'python python3 1something python'

所以这两种方法有很大的不同。

【讨论】:

  • OP 在评论中提到他已经有一个没有正则表达式的解决方案。 (但是是的,这绝对是最好的方法)
  • @brianpck,OP 还希望 "1 " 成为 "" 这样做也更有效,所以我会留下答案,因为它对未来的读者来说是一个更好的整体方法,而且它的事实做 OP 似乎想要的正确事情。
  • 实际上,您可以将生成器传递给join,而不是创建列表:" ".join(w for w in s.split() if not w.isdigit())
  • @Bahrom,如果你传递一个生成器,那会更慢,因为 python 会在内部构建一个列表,
  • 谢谢,去看看!
【解决方案3】:

这个正则表达式 (\s|^)\d+(\s|$) 可以在 javascript 中如下所示工作

var value = "1 3@bar @foo2 * 112";
var matches = value.replace(/(\s|^)\d+(\s|$)/g,"");
console.log(matches)

它分为三个部分:

  1. 它首先使用 (\s|^) 匹配空格或字符串的乞求,而 \s 匹配空格 |表示 or 和 ^ 表示字符串的开头。
  2. 下一个匹配数字从 1 到次,使用 \d 作为数字,使用 + 匹配 1 到 N 次,但尽可能多。
  3. 最后 (\s|$) 将空格或字符串结尾与 \s 匹配空格进行匹配,|意思是或,和 $ 匹配字符串的结尾。

如果你有几行,你可以用行尾或 \n 替换 $,或者像这样将它添加到它旁边 (\s|$|\n)。希望这就是您想要的。

【讨论】:

  • 这将匹配双空格
猜你喜欢
  • 2011-03-22
  • 2021-09-07
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 2014-06-20
相关资源
最近更新 更多