【问题标题】:RegEx for capturing and replacing all digits in a string except for special patternsRegEx 用于捕获和替换字符串中除特殊模式外的所有数字
【发布时间】:2019-05-25 01:33:04
【问题描述】:

我有一个文本,其中数字以各种可能的方式出现。 例如,

text = "hello23 the2e are 13 5.12apples *specially_x00123 named 31st"

我想用 '#' 替换所有数字,但以 *、单词、下划线、任何字符和数字开头的特殊模式除外,如 *\w+_[a-z]\d+(即*特别是_x00123)。

我尝试使用lookaround 语法和non-capturing group,但找不到将其完全更改为如下方式的方法

text_cleaned = "hello## the#e are ## #.##apples *specially_x00123 named ##st"

我可以使用如下模式:

p1 = r'\d(?<!\*\w+_\w+)'

然后,它就这样抱怨; "look-behind 需要固定宽度的模式"

我尝试使用非捕获组:

p2 = r'(?:\*[a-z]+_\w+)\b|\d'

它取出特殊标记(*specially_x000123)和所有数字。我认为这是我可能包含在解决方案中的内容,但我找不到如何。有什么想法吗?

【问题讨论】:

标签: python regex string replace regex-group


【解决方案1】:

您可以做的是在捕获组(\d) 中捕获数字,并在替换检查中使用回调来检查第一个捕获组。

如果是第 1 组,则替换为 #,否则返回匹配项。

由于\w+ 也匹配下划线,因此您可能首先使用否定字符类[^\W_\n]+ 匹配除下划线之外的单词char

\*[^\W_\n]+_[a-z]\d+\b|(\d)

Regex demo | Python demo

import re
text = "hello23 the2e are 13 5.12apples *specially_x00123 named 31st"
pattern = r"\*[^\W_\n]+_[a-z]\d+\b|(\d)"
print (re.sub(pattern, lambda x: "#" if x.group(1) else x.group(), text))

结果

hello## the#e are ## #.##apples *specially_x00123 named ##st

【讨论】:

  • 太棒了。我不知道我可以使用 lambda 作为替换字符串。这没有问题。
【解决方案2】:

一种选择可能是我们将字符串拆分到星号之前,然后在星号之后。表达式(\d) 捕获星号之前的每个数字,我们可以简单地使用# 替换它,然后我们将使用$2 加入它:

(\d)|(\*.*)

测试

# coding=utf8
# the above tag defines encoding for this document and is for Python 2.x compatibility

import re

regex = r"(\d)|(\*.*)"

test_str = ("hello23 the2e are 13 5.12apples *specially_x00123 named\n\n"
    "hello## the#e are ## #.##apples *specially_x00123 named")

subst = "#\\2"

# You can manually specify the number of replacements by changing the 4th argument
result = re.sub(regex, subst, test_str, 0, re.MULTILINE)

if result:
    print (result)

# Note: for Python 2.7 compatibility, use ur"" to prefix the regex and u"" to prefix the test string and substitution.

regex101.com

const regex = /(\d)|(\*.*)/gm;
const str = `hello23 the2e are 13 5.12apples *specially_x00123 named`;
const subst = `#$2`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

【讨论】:

  • 但位数不固定。我不能只计算我不想替换的所有数字
  • 不可靠。你的返回 ''hel# t#e are###apples *specially_x00123 named'
  • 这行得通。差不多~~ 'hello## the#e are ## #.##apples #*specially_x00123 named' 现在它保留了模式中的数字,但是我们在开头多了一个#。
  • 啊~好的,我明白你在做什么了。让我稍微改变一下这个问题。我可能会在特殊模式后看到数字。
  • 您的正则表达式添加在星号前面添加了一个额外的 # 例如 *specially_... 变为 #*specially_... 因为您将每个匹配替换为 #\2 这可能是不想要的.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
相关资源
最近更新 更多