* []表示字符 * [a-z] * 预定义字符 * `.`表示任意一个字符 * `.*` 表示任意多个字符 * `\d`表示任意一个数字 * `\b`表示word前后的空格 * `+` 代表的是匹配加号(+)之前的正则表达式1次或多次 * `[ab]+`和`[ab][ab]*`等价 * \w+ 匹配word * 模式 * (?i) 不区分大小写,`(?i)(invoke|call|exec|run).*function` * 匹配行首尾:行首`^`,行尾`$` * `egrep "[45]..$"` ![img](https://images2018.cnblogs.com/blog/733013/201809/733013-20180912234030307-1579497375.png) ## 例子 * 解释一下 `PAT = re.compile( r'^/(?P[-_0-9A-Za-z]+)/service/(?P[-_0-9A-Za-z]+)(/(?P[-_0-9A-Za-z]+):(?P[-_0-9A-Za-z]+))?/(?P\w+):(?P\d+)(/(?P\d+))?$' )` * `^`:表示字符串的开头。 * `/`:表示斜杠字符。 * `(?P[-_0-9A-Za-z]+)`:使用命名捕获组的语法,匹配一个或多个由字母、数字、下划线、短划线组成的字符序列,并将其命名为"bzid"。 * `/service/`:表示字面字符串"/service/"。 * `(?P[-_0-9A-Za-z]+)`:匹配一个或多个由字母、数字、下划线、短划线组成的字符序列,并将其命名为"base_name"。 * `(/(?P[-_0-9A-Za-z]+):(?P[-_0-9A-Za-z]+))?`:使用括号和问号表示的可选部分,匹配一个可选的分组,包含一个由字母、数字、下划线、短划线组成的字符序列(命名为"idc"),后跟冒号、再后跟一个由字母、数字、下划线、短划线组成的字符序列(命名为"cluster")。 * `/`:表示斜杠字符。 * `(?P\w+)`:匹配一个或多个字母、数字、下划线字符,并将其命名为"server_type"。 * `:`:表示冒号字符。 * `(?P\d+)`:匹配一个或多个数字字符,并将其命名为"index"。 * `(/(?P\d+))?`:使用括号和问号表示的可选部分,匹配一个可选的分组,包含一个或多个数字字符(命名为"replica_id")。 * `?`:表示前面的可选部分是可选的,可以出现零次或一次。 * `$`:表示字符串的结尾。 ## Python ```python PAT = re.compile( r'^/(?P[-_0-9A-Za-z]+)/service/(?P[-_0-9A-Za-z]+)(/(?P[-_0-9A-Za-z]+):(?P[-_0-9A-Za-z]+))?/(?P\w+):(?P\d+)(/(?P\d+))?$' ) path: str matched = PAT.match(path) group_dict = matched.groupdict() ``` ```python import re text = "The cat chased the cat that chased the mouse" pattern = re.compile(r"cat") matches = re.finditer(pattern, text) for match in matches: print(f"匹配位置: {match.start()} - {match.end()},匹配内容: {match.group()}") ``` * 中括弧、理解Group ```python def replace_dict_keys_in_string(my_dict, input_string): pattern = re.compile(r'(--([\w, ]+)-->)|(<--([\w, ]+)--)', re.IGNORECASE) def replace_key(match): relations = None if match.group(1) is not None: relations = match.group(2) relations = relations.split(',') translated_relation = ','.join( [my_dict[r] if r.strip() in my_dict else r for r in relations]) return f"--{translated_relation}-->" elif match.group(3) is not None: relations = match.group(4) relations = relations.split(',') translated_relation = ','.join( [my_dict[r] if r.strip() in my_dict else r for r in relations]) return f"<--{translated_relation}--" return match.group(0) new_string = re.sub(pattern, replace_key, input_string) return new_string ``` ## 技巧 ### 捕获组 ```python import re string = "Hello, World!" match = re.search(r'(\w+), (\w+)!', string) if match: print(match.group()) # 输出完整的匹配结果 "Hello, World!" print(match.group(1)) # 输出第一个捕获组的值 "Hello" print(match.group(2)) # 输出第二个捕获组的值 "World" ``` ### re.DOTALL `re.findall(r'```python\n(.*?)\n```', text, re.DOTALL)` `re.DOTALL` 是一个正则表达式的标志(也叫修饰符),它改变了 `.` 字符的默认行为。通常情况下, `.` 不匹配换行符 `\n`,但当使用了 `re.DOTALL` 标志后, `.` 就可以匹配包括换行符在内的任意字符了。在这个具体的正则表达式中,由于 Python 代码块内部很可能包含换行符,如果不使用 `re.DOTALL`, `.*?` 部分就无法完整地匹配代码块中跨越多行的内容,所以使用这个标志能确保正确地匹配到整个 Python 代码块里的所有字符,从 `python\n` 之后到 `\n` 之前的全部内容(只要满足非贪婪匹配的原则)。