当它们不是字符串的一部分时如何查找某些字符? (正则表达式,Python)

时间:2016-03-22 23:56:20

标签: python regex

我从inp = re.sub('[^A-Z]', '', inp)开始,但意识到删除了val = 0,但我想不删除字符串开头的val = 0,同时删除所有非大写字母字符其他情况。我该怎么做?

3 个答案:

答案 0 :(得分:2)

此解决方案适用于未知开头保护的子字符串的情况。

要“保护”字符串开头的特定子字符串并删除其他地方的某些字符,您需要在模式中指定替换,其中包含要保留的部分一个捕获组。然后,在替换期间,您只需要检查捕获的组是否匹配,如果是,则只需恢复结果中的值。否则,用空字符串替换。

import re
inp = "val = 20 MORE @#$TEXT.!!??"
res = re.sub(r'(^val\s*=\s*\d+)|[^A-Z]', lambda m: m.group(1) if m.group(1) else "", inp)
print(res)

请参阅IDEONE demo

模式分解:

  • (^val\s*=\s*\d+) - val后跟0 +空白符号(\s*),后跟=,后跟0 +空白符号,后跟1+位数({{1} }})在字符串的开头(\d+
  • ^ - 或
  • | - 任何非大写字母字符

注意如果您需要替换所有非字母字符,请使用[^A-Z]或在正则表达式定义中添加[A-Za-z]

答案 1 :(得分:1)

正则表达式描述常规语言的表达。在没有涉及无上下文语言的理论细节的情况下,一般来说,regexp的能力在某些方面是有限的。你要求一个正则表达式,这意味着(或多或少)“一个非大写字母的字符,它不是开头特殊部分的一部分”。一般来说,单独使用regexp并不是“可表达的”(在你的特殊情况下,“开头部分”似乎很复杂,也不是)。

我建议分两步做你想做的事:

  1. 将输入拆分为开头部分(flags=re.I),其余部分。如果起始部分不存在,则将整个输入作为其余部分。
  2. 仅对其余部分应用您的更改。
  3. 然后你可以很容易地连接这两部分并完成。

    解决方法可能是:

    val = 0

答案 2 :(得分:0)

如果您可以反转您的第二个角色组(在您的情况下通过简单地与[A-Z]交换它似乎是一个选项),您可以简单地找到您想要保留的所有部分代替:

inp = 'val = 20 FooBar'
return ''.join(re.findall(r'^[a-zA-Z_][a-zA-Z_0-9]* = [0-9]+|[A-Z]', inp))

将返回'val = 20FB'