在查看了 Kraigolas 和 Will 给出的精彩答案后,我尝试了一种仅需要一个正则表达式的不同方法。
输入(从威尔的答案中窃取:D)
import re
test_cases = (
'abc %20 def',
'abc %20 def',
'abc or def',
'abc OR def',
'abc+def',
'abc + def',
'abc&def',
'abc & def',
'abc AND def',
'abc and def',
)
如下所述捕获 5 组模式。
group1
: (\w+)\s?
捕获第一个空格之前的所有字母
group2
: ((or|OR|\+|%20)|(&|and|AND))
第 3 组和第 4 组的包装组(这使得创建一个正则表达式成为可能)
group3
: (or|OR|\+|%20)
捕获or
, OR
, +
, %20
group4
: (&|and|AND)
捕获&
, and
, AND
group5
: \s?(\w+)
捕获最后一个空格之后的所有字母。
注意\s?
捕获 1 个或 0 个空格。
pattern = re.compile(r'(\w+)\s?((or|OR|\+|%20)|(&|and|AND))\s?(\w+)')
格式化字符串如下。如果组 3 退出则替换为OR
。否则替换为AND
。 (请注意,当组 3 为空时,组 4 为非空,反之亦然。)
def format_value(text):
match = pattern.match(text)
if match is not None and match.group(3):
return pattern.sub(r'*\1* OR *\5*', text)
else:
return pattern.sub(r'*\1* AND *\5*', text)
for x in test_cases:
print(format_value(x))
Output
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* AND *def*
*abc* AND *def*
*abc* AND *def*
*abc* AND *def*
EDIT捕捉abc def ghi
这是一个小技巧。
创建另一个图案来捕捉空间。这不会捕获两侧带有 * 的已格式化字符串,因为我正在搜索由 2 个单词字符包围的空格。
space_pattern = re.compile(r'(\w)(\s)(\w)')
通过删除前导和尾随星号来更新格式值方法。
def format_value(text):
match = pattern.match(text)
if match is not None and match.group(3):
return pattern.sub(r'\1* OR *\5', text)
else:
return pattern.sub(r'\1* AND *\5', text)
按如下方式重新格式化字符串并添加尾随和前导星号。
for x in test_cases:
formatted_value = format_value(x)
print("*" + space_pattern.sub(r'\1* OR *\3', formatted_value) + "*")
Output
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* OR *def*
*abc* AND *def*
*abc* AND *def*
*abc* AND *def*
*abc* AND *def*
*abc*
*abc* OR *def* OR *ghi*