正则表达式 - 使用python中的re.sub将文本中的所有字母设为小写但排除特定的字符串?

时间:2018-04-29 15:20:25

标签: python-3.x

我正在编写一个脚本,使用正则表达式将文本中的所有大写字母转换为小写字母,但不包括特定的字符串/字符,例如“TEA”,“CHI”,“I”,“@ Begin”,“@Language “,”ENG“,”@参与者“,”@ Media“,”@ Transcriber“,”@ Active“,”SBR“,”@评论“等。

我现在的脚本如下所示。但是,它不能提供所需的输出。例如,当我输入“@Activities:SBR”时,给出的输出是“@ Activities @ activities:sbr @ activities:sbrSBR”。预期输出为“@Activities”:“SBR”。

我正在使用Python 3.5.2

有人可以帮忙提供一些指导吗?谢谢。

import os
from itertools import chain
import re

def lowercase_exclude_specific_string(line):
    line = line.strip()
    PATTERN = r'[^TEA|CHI|I|@Begin|@Language|ENG|@Participants|@Media|@Transcriber|@Activities|SBR|@Comment]'
    filtered_line = re.sub(PATTERN, line.lower(), line)
    return filtered_line

1 个答案:

答案 0 :(得分:1)

首先,让我们看看你输出错误的原因。

  

例如,当我输入" @Activities:SBR"时,给出的输出是   " @ Activities @ activities:sbr @ activities:sbrSBR"。

这是因为你的代码

PATTERN = r'[^TEA|CHI|I|@Begin|@Language|ENG|@Participants|@Media|@Transcriber|@Activities|SBR|@Comment]'
filtered_line = re.sub(PATTERN, line.lower(), line)

正在进行否定的字符类匹配,这意味着它将匹配列表中 的所有 字符 并用line.lower()替换它们(这是" @activities:sbr")。您可以在此regex demo中看到匹配的字符。

代码将匹配":"和" " (空白)并用" @activities:sbr"替换它们,给你结果" @Activities @activities: sbr@activities: sbr SBR"。

现在修复该代码。不幸的是,没有直接的方法来否定一行中的 单词 ,并在 其他单词 上应用替换同一行。相反,您可以先将split行划分为单个单词,然后使用re.sub对其应用PATTERN。此外,您应该使用negative lookahead

,而不是否定字符类
  

(?!...)
      否定先行断言。这与积极主张相反;如果包含的表达式匹配,则成功   字符串中的当前位置。

这是我得到的代码:

def lowercase_exclude_specific_string(line):
    line = line.strip()
    words = re.split("\s+", line)
    result = []
    for word in words:
        PATTERN = r"^(?!TEA|CHI|I|@Begin|@Language|ENG|@Participants|@Media|@Transcriber|@Activities|SBR|@Comment).*$"
        lword = re.sub(PATTERN, word.lower(), word)
        result.append(lword)
    return " ".join(result)

re.sub只会匹配PATTERN中的字词而不是,并将其替换为小写的值。如果该字词是排除模式的一部分,则该字词将无法匹配且re.sub returns it unchanged

然后将每个单词存储在一个列表中,然后再join以形成该行。

样品:

print(lowercase_exclude_specific_string("@Activities: SBR"))
print(lowercase_exclude_specific_string("@Activities: SOME OTHER TEXT SBR"))
print(lowercase_exclude_specific_string("Begin ABCDEF @Media @Comment XXXX"))
print(lowercase_exclude_specific_string("@Begin AT THE BEGINNING."))
print(lowercase_exclude_specific_string("PLACE @Begin AT THE MIDDLE."))
print(lowercase_exclude_specific_string("I HOPe thIS heLPS."))

@Activities: SBR
@Activities: some other text SBR
begin abcdef @Media @Comment xxxx
@Begin at the beginning.
place @Begin at the middle.
I hope this helps.

修改
正如评论中所提到的,显然在:和下一个字符之间有一个标签。由于代码使用\s拆分字符串,因此该选项卡无法保留,但可以通过将:替换为来恢复 :\t在最终结果中。

return " ".join(result).replace(":", ":\t")