为什么正则表达式在子串中搜索“不完全等同于Python中的切片”?

正如 documentation所述,使用regex.search(string,pos,endpos)并不完全等价于对字符串进行切片,即regex.search(string [pos:endpos])。它不会像正则表达式匹配,就像字符串从pos开始一样,所以^不匹配子字符串的开头,而只匹配整个字符串的真正开始。但是,$匹配子串或整个字符串的末尾。
>>> re.compile('^am').findall('I am falling in code',2,12)
    []        # am is not at the beginning
    >>> re.compile('^am').findall('I am falling in code'[2:12])
    ['am']    # am is the beginning
    >>> re.compile('ing$').findall('I am falling in code',12)
    ['ing']   # ing is the ending
    >>> re.compile('ing$').findall('I am falling in code'[2:12])
    ['ing']   # ing is the ending

    >>> re.compile('(?<= )am').findall('I am falling in code',12)
    ['am']    # before am there is a space
    >>> re.compile('(?<= )am').findall('I am falling in code'[2:12])
    []        # before am there is no space
    >>> re.compile('ing(?= )').findall('I am falling in code',12)
    []        # after ing there is no space
    >>> re.compile('ing(?= )').findall('I am falling in code'[2:12])
    []        # after ing there is no space

    >>> re.compile(r'\bm.....').findall('I am falling in code',3,11)
    []
    >>> re.compile(r'\bm.....').findall('I am falling in code'[3:11])
    ['m fall']
    >>> re.compile(r'.....n\b').findall('I am falling in code',11)
    ['fallin']
    >>> re.compile(r'.....n\b').findall('I am falling in code'[3:11])
    ['fallin']

我的问题是…为什么开始和结束比赛之间不一致?为什么使用pos和endpos将结束视为实际结尾,但是开始/开始不被视为真正的开始/开始?

有没有办法使用pos和endpos模仿切片?因为Python copies string when slicing而不是仅仅引用旧的,所以在使用大字符串多次时,使用pos和endpos而不是切片会更有效率。

起始位置参数pos对于进行词法分析器尤其有用。使用[pos:]切片字符串和使用pos参数之间的性能差异可能看起来不重要,但肯定不是这样;请参阅 JsLex lexer中的这个错误报告。

实际上,^匹配在字符串的真实开头;或者,如果指定了MULTILINE,也在行的开头;这也是通过设计使得基于正则表达式的扫描仪可以容易地区分输入的行/开始的真实开始和输入之间的线/内的某个其他点。

请注意,您也可以使用regex.match(string[,pos[,endpos]])功能将匹配锚定到起始字符串或由pos指定的位置;因此而不是做

>>> re.compile('^am').findall('I am falling in code',12)
[]

你一般会实现扫描仪

>>> match = re.compile('am').match('I am falling in code',12)
>>> match
<_sre.SRE_Match object; span=(2,4),match='am'>

然后将pos设置为match.end()(在这种情况下返回4)用于连续匹配操作。

匹配必须从pos开始找到:

>>> re.compile('am').match('I am falling in code',1,12)
>>>

(注意.match如何在输入的开头锚定,就像隐含的^而不是输入的结尾;确实这往往是一个错误的根源,因为人们认为这个匹配有隐含的^和$ – Python 3.4添加regex.fullmatch这样做)

至于为什么endpos参数与pos不一致 – 我不太清楚,但是对我来说也是有意义的,就像在Python 2中一样,没有完全匹配,并且锚定与$是唯一的方式来确保整个跨度必须匹配。

相关文章

正则替换html代码中img标签的src值在开发富文本信息在移动端...
正则表达式
AWK是一种处理文本文件的语言,是一个强大的文件分析工具。它...
正则表达式是特殊的字符序列,利用事先定义好的特定字符以及...
Python界一名小学生,热心分享编程学习。
收集整理每周优质开发者内容,包括、、等方面。每周五定期发...