说我有一个字符串:
"a bb c exclude_start d 3 f g h _ k l . exclude_end n 0 P exclude_start q r exclude_end s"
并说我要应用一个upper
函数,该函数将返回:
"A BB C exclude_start d 3 f g h _ k l . exclude_end N 0 P exclude_start q r exclude_end S"
我想要一个允许n
个排除块的解决方案,并将upper
函数仅应用于这些块之外的字符。
如果有一种方法可以regex
仅匹配excludes
之外的字符串,然后仅对它们应用upper
,那就太好了。
答案 0 :(得分:1)
我不确定是否可以通过单个正则表达式来做到这一点,但这是我的思考过程。我想我们想将字符串分开,以便我们只能大写不在exclude块中的部分。这样做的方法是使一个正则表达式匹配exclude块:
>>> import re
>>> exclude_pattern = re.compile(r'(exclude_start.*?exclude_end)')
我们需要在其中添加问号,以免贪婪地匹配。
由于我们要保留与我们的exclude_pattern
匹配的字符串部分,而不是仅仅丢弃它们,因此我们可以使用re.split
:
如果在模式中使用了捕获括号,则模式中所有组的文本也会作为结果列表的一部分返回。
这就是为什么我们在exclude_pattern
中需要括号。
接下来,我们要使用该模式分割字符串:
>>> input_string = "a bb c exclude_start d 3 f g h _ k l . exclude_end n 0 P exclude_start q r exclude_end s"
>>> exclude_pattern.split(input_string)
['a bb c ', 'exclude_start d 3 f g h _ k l . exclude_end', ' n 0 P ', 'exclude_start q r exclude_end', ' s']
这给了我们所需的分离。
我们接下来要做的就是upper
仅匹配与我们的排除模式不匹配的字符串。为此,我们可以在列表上映射一个lambda,以根据排除模式检查每个条目,并且仅upper
匹配不匹配的条目:
>>> list(map(lambda s: s.upper() if not exclude_pattern.match(s) else s, exclude_pattern.split(input_string)))
['A BB C ', 'exclude_start d 3 f g h _ k l . exclude_end', ' N 0 P ', 'exclude_start q r exclude_end', ' S']
list()
只是为了让我们可以看到生成的地图对象中的内容。
之后,我们将它们重新结合在一起:
>>> ''.join(map(lambda s: s.upper() if not exclude_pattern.match(s) else s, exclude_pattern.split(input_string)))
'A BB C exclude_start d 3 f g h _ k l . exclude_end N 0 P exclude_start q r exclude_end S'
如果您不想将它作为单行代码使用(这有点麻烦),我们可以将其变成一个函数:
def excluded_upper(input_string):
exclude_pattern = re.compile(r'(exclude_start.*?exclude_end)')
split_string = exclude_pattern.split(input_string)
output = []
for s in split_string:
if exclude_pattern.match(s):
output.append(s)
else:
output.append(s.upper())
return ''.join(output)