我想匹配一个字符串直到一个终端字符/序列,其中:
- 终端字符/序列不是匹配的一部分。
- 终端字符/序列是定义的集合之一,比方说
(',',':', '%%')
。 - 转义的终端字符/模式不充当终止符。
- 转义的反斜杠将被使用,而不是用于转义后面的字符。
- 字符串结尾也会终止匹配,即使前面有转义字符。
- 换行符
(LF,CR)
也可以作为终止符,即使前面有转义符。他们也不是比赛的一部分(但如果有的话,最后一个悬空逃脱是)。
所以核心问题:一些终结者序列被转义符中和,而另一些则没有。
这些是一些示例字符串及其所需的匹配结果:字符序列将被视为原始,但我正在使用<newline>
for (LF,CR)
(即原始换行符,如 in U+000A, U+000D
)
1: xxx\,aaa,bbb --> xxx\,aaa
2: xxx\\:aaa,bbb --> xxx\\
3: xxx\\\\\,aaa\::bbb --> xxx\\\\\,aaa\:
4: xxx%%aaa --> xxx
5: xxx\%%aaa --> xxx\%%aaa
6: xxx%\%bbb\ --> xxx%\%bbb\
7: xxx\,aaa<newline>bbb --> xxx\,aaa
8: xxx\,aaa\<newline>bbb --> xxx\,aaa\
9: x\xa\a\,bb\\,bb --> x\xa\a\,bb\\
按照这里关于 SO 的其他一些问题的风格,我设法做到了这一点:
pat = re.compile(r'.+?(?<!\\)(\\\\)*(?=[:,\n\r]|%%|$)', re.DOTALL|re.UNICODE)
但这并没有涵盖所有规则,它存在转义换行符和转义字符串结尾的问题。
编辑: 反斜杠可以出现在任何字符之前而不会导致不匹配(参见示例 9),只是如果它出现在另一个反斜杠之前,它会抵消其作为转义字符的效果,如果它出现在某些终止符之前,它会将它们的效果抵消为终结者。