[从我以前的question跟进,提供更好的描述和链接]
尝试在两个符号(包括这些符号)之间匹配任何字符(包括换行符、制表符、空格等)。在
例如:
foobar89\n\nfoo\tbar; '''blah blah blah'8&^"'''
需要匹配
''blah blah blah'8&^"'''
以及
fjfdaslfdj; '''blah\n blah\n\t\t blah\n'8&^"'''
需要匹配
'''blah\n blah\n\t\t blah\n'8&^"'''
我的Python代码(取自并改编自here),我在其中测试正则表达式:
import collections
import re
Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column'])
def tokenize(code):
token_specification = [
('BOTH', r'([\'"]{3}).*?\2'), # for both triple-single quotes and triple-double quotes
('SINGLE', r"('''.*?''')"), # triple-single quotes
('DOUBLE', r'(""".*?""")'), # triple-double quotes
# regexes which match OK
('COM', r'#.*'),
('NEWLINE', r'\n'), # Line endings
('SKIP', r'[ \t]+'), # Skip over spaces and tabs
('MISMATCH',r'.'), # Any other character
]
test_regexes = ['COM', 'BOTH', 'SINGLE', 'DOUBLE']
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group(kind)
if kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
elif kind == 'SKIP':
pass
elif kind == 'MISMATCH':
pass
else:
if kind in test_regexes:
print(kind, value)
column = mo.start() - line_start
yield Token(kind, value, line_num, column)
f = r'C:\path_to_python_file_with_examples_to_match'
with open(f) as sfile:
content = sfile.read()
for t in tokenize(content):
pass #print(t)
其中file_with_examples_to_match
是:
从this answer开始,我尝试r"('''.*?''')|"r'(""".*?""")
匹配三个单引号和三个双引号的情况,但没有成功。尝试r'([\'"]{3}).*?\2')
时相同。在
我已经设置了一个onlineregex测试程序,其中一些regex确实与它们应该匹配,但是在上面的代码中它们失败了。在
我对理解Python的正则表达式很感兴趣,所以我希望能有一个解决方案(也许是一个有效的正则表达式来对代码进行所需的匹配)和一个简短的解释,这样我就可以看到我的缺点了。在
您可能缺少使
.
与换行符匹配的标志在这种情况下,输出是
^{pr2}$
^{3}$COM
现在匹配的方式太多了,因为.
现在将所有内容都放到文件末尾。如果我们稍微修改一下这个模式,让它不那么贪婪我们现在可以使用
re.MULTILINE
来减少匹配现在的输出是
如果您确实不想使用标志,那么可以使用一种“hack”来不使用
.
,因为这个元字符几乎匹配所有内容,除了换行符。您可以创建一个匹配组,它将匹配除一个符号之外的所有内容,该符号不太可能出现在要解析的文件中。例如,可以将字符与ASCII代码0一起使用。这种字符的Regex将是\x00
,对应的模式[^\x00]
将匹配每个符号(甚至换行符),除了ASCII代码为0的符号(这就是为什么它是一个黑客,你不能匹配没有标志的每个符号)。您需要为COM
保留初始regex,而对于BOTH
则需要保留强烈建议使用解释regex的在线工具,如regex101
对于更复杂的引号匹配情况,您需要编写一个解析器。例如,请参见thisCan the csv format be defined by a regex?和thisWhen you should NOT use Regular Expressions?。在
相关问题 更多 >
编程相关推荐