如果对你有帮助,就点个赞吧~
一、正则 分组 + 反引用 的使用情景
1. 网上获取的书名有重复的情况, 怎么找出来进行去重呢?
如: 伯罗奔尼撒战争史,伯罗奔尼撒战争史
正则: re.search(r"([\u4e00-\u9fff]+),\1", "伯罗奔尼撒战争史,伯罗奔尼撒战争史")
就可以把此类重复给找到.
解释: 前面的`()`是将逗号前面的部分当做一个分组, 此时, 这个分组的索引就是 1(是从1开始的), 逗号后面的`\1`, 就是引用这个前面的分组, 那就是说逗号后是重复前面的分组内容
如果中间有其他的分隔符, 可以使用非中文的字符来替换上面正则的`,`
如: `伯罗奔尼撒战争史{伯罗奔尼撒战争史`
re.search(r"([\u4e00-\u9fff]+)[^\u4e00-\u9fff]\1", "伯罗奔尼撒战争史{伯罗奔尼撒战争史")
解释: `[]`里面的第一个字符是`^`表示取反, `[^\u4e00-\u9fff]` 表示取的是非中文
如果有多个重复
如: `伯罗奔尼撒战争/伯罗奔尼撒战争史/伯罗奔尼撒战争史`
re.search(r"([\u4e00-\u9fff]+)(?:[^\u4e00-\u9fff]\1)+", "伯罗奔尼撒战争/伯罗奔尼撒战争史/伯罗奔尼撒战争史")
解释: `(?:)`含义是说, 此括号内的内容不算作分组, 但是仍是当做一个整体, 不会像前面的`([\u4e00-\u9fff]+)` 是有分组的序号 1,
`(?:[^\u4e00-\u9fff]\1)+`是将括号内的内容多次重复的意思
2. 网上获得的书名中间有空格
如: `伯罗奔 尼撒 战争史`
通过正则替换: 就可以去掉中间的空格
re.sub(r"([\u4e00-\u9fff]+) ([\u4e00-\u9fff]+) ([\u4e00-\u9fff]+)", r"\1\2\3", "伯罗奔 尼撒 战争史")
解释: python中正则表达式, 前面要有一个`r`字母, 后面替换的三个分组`r"\1\2\3"`记得是必须要的
二、正则的前视后视使用
前视: 按文本从左向右读, 右边为前, 就是说 所要匹配的文本的后面跟随的条件, 如: `战争是争地盘`, 想提取`地`前面的`争`
re.search(r"争(?=地)", "战争是争地盘")
此时结果是: `<re.Match object; span=(3, 4), match='争'>`
re.search(r"争", "战争是争地盘")
结果是: `<re.Match object; span=(1, 2), match='争'>`, 此时匹配的是第一个`争`
后视: 按上面的说的顺序, 左边的文本用来做为条件, 如: `战争是争地盘`, 想提取`是`后面的`争`
re.search(r"(?<=是)争", "战争是争地盘")
此时结果是: `<re.Match object; span=(3, 4), match='争'>`
re.search(r"争", "战争是争地盘")
结果是: `<re.Match object; span=(1, 2), match='争'>`, 此时匹配的是第一个`争`
前后视总结:
个人感觉, 不计较什么前视后视,
- 后面文本做条件, 条件就写后面`争(?=地)`, 如果要选争后面不是`地`的, 那就是 `争(?!地)`
- 前面文本做条件, 条件就写前面`(?<=是)争`, 如果要选争前面不是`是`的, 那就是 `(?<!是)争`
放前面的条件, 多了个`<`(小于号)
这里只记述了部分用法, 其他详细可以参考 正则入门整理