我正在编写一个脚本,使用正则表达式将文本中的所有大写字母转换为小写字母,但不包括特定的字符串/字符,例如“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
答案 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")