python - 将字符串中的数字转换为 `_NUM-*_` 符号

标签 python regex string replace numbers

给定一个带有数字的字符串:

I counted, ' 1 2 3 4 5 5 5 8 9 10 '

目标是将数字转换为 _NUM-*_ 符号,其中 * 表示数字出现的顺序。例如。给定上述 intpu 所需的输出是:

"I counted, ' _NUM-1_ _NUM-2_ _NUM-3_ _NUM-4_ _NUM-5_ _NUM-6_ _NUM-7_ _NUM-8_ _NUM-9_ _NUM-10_'"

即使是重复的数字,例如给定输入

I said, ' 1 2 3 4 5 5 5 8 9 10 '

所需的输出保持数字的顺序,忽略数字本身的值,例如:

"I said, ' _NUM-1_ _NUM-2_ _NUM-3_ _NUM-4_ _NUM-5_ _NUM-6_ _NUM-7_ _NUM-8_ _NUM-9_ _NUM-10_'" 

我已经尝试过:

import re

s = "I counted, ' 1 2 3 4 5 6 7 8 9 10 '"
num_regexp = '(?<!\S)(?=.)(0|([1-9](\d*|\d{0,2}(,\d{3})*)))?(\.\d*[1-9])?(?!\S)'


re.sub(num_regexp, '_NUM_', s)

但它只是用相同的 _NUM_ 符号替换输出,而不保持顺序,即

[输出]:

"I counted, ' _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ _NUM_ '"

我可以执行 post re.sub 操作并替换每个 _NUM_,即

import re

s = "I counted, ' 1 2 3 4 5 6 7 8 9 10 '"
num_regexp = '(?<!\S)(?=.)(0|([1-9](\d*|\d{0,2}(,\d{3})*)))?(\.\d*[1-9])?(?!\S)'

num_counter = 1
tokens = []
for token in re.sub(num_regexp, '_NUM_', s).split():
    if token == '_NUM_':
        token = '_NUM-{}_'.format(num_counter)
        num_counter += 1

    tokens.append(token)

result = ' '.join(tokens)

[输出]:

"I counted, ' _NUM-1_ _NUM-2_ _NUM-3_ _NUM-4_ _NUM-5_ _NUM-6_ _NUM-7_ _NUM-8_ _NUM-9_ _NUM-10_ '"

是否有更好的方法来实现所需的输出,而无需先进行通用 re.sub 然后进行事后字符串编辑?

最佳答案

使用itertools.count作为传递给 re.sub 的函数的默认参数。

>>> from itertools import count

>>> re.sub('(\d+)', lambda m, c=count(1): '_NUM_-{}'.format(next(c)), s)
' _NUM_-1 _NUM_-2 _NUM_-3 _NUM_-4 _NUM_-5 _NUM_-6 _NUM_-7 _NUM_-8 _NUM_-9 _NUM_-10 '

请注意,我使用简化的正则表达式来匹配数字只是为了演示如何获取计数,您可以将其替换为也匹配 float 的正则表达式。

关于python - 将字符串中的数字转换为 `_NUM-*_` 符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45626038/

相关文章:

python - urllib.urlopen 有效,但 urllib2.urlopen 无效

python - 这条新线从哪里来?

javascript - 应用程序版本验证的 RegExp 应该是什么?

jquery - 如何从正则表达式中排除特殊字符?

java - 在引号外用逗号分割

python - 如何在 python 中显示文件中的西里尔文本?

python - 如何比较 Pandas 中的时间频率?

python - re.findall 表现得很奇怪

javascript - 用于匹配除逗号分隔数字以外的所有字符的正则表达式

python - 具有非重复字符的最长子串