- 正则表达式pattern一定要使用raw string形式,即使用 r"..." 形式,这是因为包括 '\b'、'\1' 等字符,既是ASCII特殊字符,又是正则表达式特殊字符。如果在pattern string中没有使用 r"..." 形式,则必须使用形如 "\\b"、"\\1" 这样的转义表达,否则python解释器将会首先把 "\b" 当做ASCII特殊字符中的回退字符处理,把 "\1" 当做八进制的数来处理,这样就会出现形如 re.findall("\bthe\b", "the python is the best") 结果却为空列表的怪事。使用了raw string的形式之后,python解释器不会对字符串中的反斜线 "\" 进行转义处理,完整的 "\b" 会被发送至正则表达引擎,这样才会被当做单词边界标志来处理。
- 在正则表达式pattern中使用 (?P<group_name>...) 扩展模式时,如果...部分匹配成功,则可以在三种情况下使用 "groupName" 来对匹配内容进行检索和使用,被测字符串 strTest = "010 : 010-12345678"
(1)、 pattern 字符串本身中使用 (?P=group_name)来引用匹配成功的内容,例如 result = re.match(r"(?P<areacode>\b\d+\b)[ ]:[ ](?P=areacode)-(?P<number>\d+)", strTest)
(2)、 match object中可以使用 match.group("group_name") 来引用匹配的内容,例如 result.group("areacode") 或者 result.groupdict("areacode") 结果为 "010"
(3)、 在正则匹配替换方法的repl参数中,可以使用 \g<group_name> 来引用pattern中匹配的内容,例如 re.sub(r"(?P<areacode>\b\d+\b)[ ]:[ ](?P=areacode)-(?P<number>\d+)", "\g<areacode> - (\g<areacode>)\g<number>", strTest) 结果为 '010 - (010)12345678',上述语句等效于 re.sub(r"(\b\d+\b)[ ]:[ ]\1-(\d+)", "\g<1> - (\g<1>)\g<2>", strTest) - 扩展表达式 (?:...) 的主要作用是,用于构建包含符合指定匹配规则的子字符串(即...的正则表达式匹配的内容),且匹配的子字符串我们并不关注它的具体内容的匹配内容,该匹配内容作为整体可以和*、?、+、| 等特殊字符配合使用时进行占位,最终这样的匹配内容不会保存到match object的groups中。例如需要判断一个字符串是否是合法的email地址,并且从中提取出邮箱名来:
>>>re.search(r"\b(?P<emailName>(?:\w|[\.-])+)@(?P<suffix>(?:\w+\.)+(?P<type>\w+))", "ralph.test-2@yahoo.com.cn").groups()
pattern中的 (?:\w|[\.-]) 和 (?:\w+\.) 都是匹配了一个子字符串,并和+字符配合来进行复杂的占位,但是并没有在最终的匹配结果的group中保存这两个匹配结果
('ralph.test-2', 'yahoo.com.cn', 'cn') - 对于在pattern中使用 (...) 或 (?P<name>...) 方式进行匹配并保存的内容,如果没有匹配成功,仍然会在结果的group中占用一个结果,只是值为None。例如:
>>> re.search(r"(?:(?P<areacode>\b\d+\b)(?:\s*-\s*))?(?P<number>\b\d+\b)", "0755 - 12345678").groups()
('0755', '12345678')
>>> re.search(r"(?:(?P<areacode>\b\d+\b)(?:\s*-\s*))?(?P<number>\b\d+\b)", "12345678").groups()
(None, '12345678') - 对于上例这种 re.search(r"(?:(?P<areacode>\b\d+\b)(?:\s*-\s*))?(?P<number>\b\d+\b)", "0755 - 12345678").groups() 较复杂的pattern,最好使用 re.VERBOSE 或 re.X 标志,或者使用 (?x) 扩展表达式方式来格式化书写,并加入注释例如:
>>> re.search(r"""(?x)
(?:
(?P<areacode>\b\d+\b) # the area code group
(?:\s*-\s*) # the connection token
)? # the possible whole area code part
(?P<number>\b\d+\b) # the phone number group
""", "0755-12345678").groupdict()
{'areacode': '0755', 'number': '12345678'} - 每一个match object都有至少一个group,其值为match object对应的子字符串,即执行matchObj.goup() 或 matchObj.group(0) 都将返回完整的匹配子字符串。当pattern中通过(...)或(?P<name>...)方式定义了其他的group时,matchObj.group(N)将会返回对应的group子字符串。
而match object的 groups() 函数则会一个tuple,其中的每个值对应于在pattern中通过(...)或(?P<name>...)方式定义的一个group匹配的子字符串,如果pattern中没有定义group则groups()函数返回的是一个空tuple。
——因此 matchObj.group(N) 的值等同于 matchObj.groups()[N-1],N>0 - re.search() 函数:
对目标字符串从左至右进行扫描,一旦发现符合pattern的子字符串(但符合pattern的子字符串的起点并不一定等于目标字符串的起点),就停止继续向右扫描,而返回match object
re.match() 函数:
对目标字符串从最左侧开始处进行pattern模式的匹配,如果向右移动至某个位置时匹配成功,就停止继续向右扫描,而返回match object
re.findall() 函数:
对目标字符串从左至右进行扫描,将会扫描直至目标字符串的结尾,并查找出整个目标字符串中所有符合pattern的子字符串,并返回这些子字符串对应的match object的groups()函数返回的tuple构成的list,如果每个match object的groups()函数返回的是空tuple,则findall()返回的则是多个匹配pattern的子字符串构成的list
re.finditer()函数:
的工作方式与findall()类似,只是其返回值不是一个常驻内存的list,而是一个generator,当遍历这个generator时,实时运算得到一个match object并返回,当一次遍历完成后,这个generator中的内容也就销毁不再占用内存空间了,即再次对这个generator进行遍历不会得到任何内容了
——因此search和match函数最多只能得到一个匹配对象,而findall和finditer函数能够得到所有的匹配对象,示例如下:
>>>strTest = '010 : 010-12345678\nBeijing\n020 : 020-23456789\nGuangzhou\n021 : 021-34567890\nShanghai'>>> re.search(r"(?sm)^(?P<areacode>\d+)[ ]:[ ](?P=areacode)-(?P<number>\d+).+?(?P<name>\b\w+\b)$",strTest).groups()
('010', '12345678', 'Beijing')>>> re.findall(r"(?sm)^(?P<areacode>\d+)[ ]:[ ](?P=areacode)-(?P<number>\d+).+?(?P<name>\b\w+\b)$",strTest)
[('010', '12345678', 'Beijing'), ('020', '23456789', 'Guangzhou'), ('021', '34567890', 'Shanghai')]>>> result = re.finditer(r"(?sm)^(?P<areacode>\d+)[ ]:[ ](?P=areacode)-(?P<number>\d+).+?(?P<name>\b\w+\b)$",strTest)
>>> for item in result:
print item.groups()('010', '12345678', 'Beijing')
('020', '23456789', 'Guangzhou')
('021', '34567890', 'Shanghai')
>>> for item in result:
print item.groups()>>>
转载于:https://www.cnblogs.com/xaviercd/p/5821119.html