Smurf
文章50
标签0
分类6
Regular Expression

Regular Expression

正则表达式操作

re—- 正则表达式操作

  • 正则表达式可以拼接;如果 AB 都是正则表达式,则 AB 也是正则表达式。
  • 正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如 'A', 'a', 或者 '0',都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以 last 匹配字符串 'last'.
  • 有些字符,比如 '|' 或者 '(',属于特殊字符。 特殊字符既可以表示它的普通含义, 也可以影响它旁边的正则表达式的解释。
  • 重复修饰符 (*, +, ?, {m,n}, 等) 不能直接嵌套。这样避免了非贪婪后缀 ? 修饰符,和其他实现中的修饰符产生的多义性。要应用一个内层重复嵌套,可以使用括号。 比如,表达式 (?:a{6})* 匹配6个 'a' 字符重复任意次数。

特殊字符有:

  • .

    (点) 在默认模式,匹配除了换行的任意字符。如果指定了标签 DOTALL ,它将匹配包括换行符的任意字符。

  • ^

    (插入符号) 匹配字符串的开头, 并且在 [MULTILINE] 模式也匹配换行后的首个符号。

  • $

    匹配字符串尾或者在字符串尾的换行符的前一个字符,在 MULTILINE模式下也会匹配换行符之前的文本。 foo 匹配 ‘foo’ 和 ‘foobar’,但正则表达式 foo$ 只匹配 ‘foo’。 更有趣的是,在 'foo1\nfoo2\n' 中搜索 foo.$,通常匹配 ‘foo2’,但在 [MULTILINE]模式下可以匹配到 ‘foo1’;在 'foo\n' 中搜索 $ 会找到两个(空的)匹配:一个在换行符之前,一个在字符串的末尾。

  • *

    对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 ab* 会匹配 'a''ab',或者 'a' 后面跟随任意个 'b'

  • +

    对它前面的正则式匹配1到任意次重复。 ab+ 会匹配 'a' 后面跟随1个以上到任意个 'b',它不会匹配 'a'

  • ?

    对它前面的正则式匹配0到1次重复。 ab? 会匹配 'a' 或者 'ab'

  • *?, +?, ??

    '*', '+',和 '?' 修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。如果正则式 <.*> 希望找到 '<a> b <c>',它将会匹配整个字符串,而不仅是 '<a>'。在修饰符之后添加 ? 将使样式以 非贪婪方式或者 :dfn:最小 方式进行匹配; 尽量 的字符将会被匹配。 使用正则式 <.*?> 将会仅仅匹配 '<a>'

  • {m}

    对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如, a{6} 将匹配6个 'a' , 但是不能是5个。

  • {m,n}

    对正则式进行 mn 次匹配,在 mn 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如 a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b',但不能匹配 'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。

  • {m,n}?

    前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。比如,对于 'aaaaaa'a{3,5} 匹配 5个 'a' ,而 a{3,5}? 只匹配3个 'a'

  • \

    转义特殊字符(允许你匹配 '*', '?', 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。
    如果你没有使用原始字符串( r'raw' )来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。

  • []

    用于表示一个字符集合。在一个集合中:

    • 字符可以单独列出,比如 [amk] 匹配 'a''m', 或者 'k'

    • 可以表示字符范围,通过用 '-' 将两个字符连起来。比如 [a-z] 将匹配任何小写ASCII字符, [0-5][0-9] 将匹配从 0059 的两位数字, [0-9A-Fa-f] 将匹配任何十六进制数位。 如果 - 进行了转义 (比如 [a\-z])或者它的位置在首位或者末尾(如 [-a][a-]),它就只表示普通字符 '-'

    • 特殊字符在集合中,失去它的特殊含义。比如 [(+*)] 只会匹配这几个文法字符 '(', '+', '*', or ')'

    • 字符类如 \w 或者 \S (如下定义) 在集合内可以接受,它们可以匹配的字符由 [ASCII]模式决定。

    • 不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 '^' ,所有 在集合内的字符将会被匹配,比如 [^5] 将匹配所有字符,除了 '5'[^^] 将匹配所有字符,除了 '^'. ^ 如果不在集合首位,就没有特殊含义。

    • 在集合内要匹配一个字符 ']',有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如, [()[\]{}][]()[{}] 都可以匹配括号
  • |

    `A|BAB 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用 '|' 连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|' 操作符绝不贪婪。 如果要匹配 '|' 字符,使用 \|, 或者把它包含在字符集里,比如 [|].

  • (...)
    (组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 '(' 或者 ')', 用 \(\), 或者把它们包含在字符集合里: [(], `[)]``

  • (?…)

    这是个扩展标记法 (一个 '?' 跟随 '(' 并无含义)。 '?' 后面的第一个字符决定了这个构建采用什么样的语法。

  • `(?aiLmsux)

    ( 'a', 'i', 'L', 'm', 's', 'u', 'x' 中的一个或多个) 这个组合匹配一个空字符串;

  • (?:…)

    正则括号的非捕获版本。 匹配在括号内的任何正则表达式,但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。

  • (?aiLmsux-imsx:…)

    ('a', 'i', 'L', 'm', 's', 'u', 'x' 中的0或者多个, 之后可选跟随 '-' 在后面跟随 'i' , 'm' , 's' , 'x' 中的一到多个 .)

  • (?#…)

    注释;里面的内容会被忽略。

  • \number:\1

    匹配数字代表的组合。每个括号是一个组合,组合从1开始编号。比如 (.+) \1 匹配 'the the' 或者 '55 55', 但不会匹配 'thethe' (注意组合后面的空格)。这个特殊序列只能用于匹配前面99个组合。如果 number 的第一个数位是0, 或者 number 是三个八进制数,它将不会被看作是一个组合,而是八进制的数字值。在 '['']' 字符集合内,任何数字转义都被看作是字符。

  • \b

    匹配空字符串,但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。注意,通常 \b 定义为 \w\W 字符之间,或者 \w 和字符串开始/结尾的边界, 意思就是 r'\bfoo\b' 匹配 'foo', 'foo.', '(foo)', 'bar foo baz' 但不匹配 'foobar' 或者 'foo3'

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    k = re.findall(r'\bfoo\b', 'foo')
    print(k)

    k = re.findall(r'\bfoo\b', '(foo)')
    print(k)

    k = re.findall(r'\bfoo\b', 'foo.')
    print(k)

    k = re.findall(r'\bfoo\b', 'bar foo bar')
    print(k)

    k = re.findall(r'\bfoo\b', 'foo3')
    print(k)
    output: [‘foo’] [‘foo’] [‘foo’] [‘foo’] []
  • \s

    • 对于 Unicode (str) 样式:

      匹配任何Unicode空白字符(包括 [ \t\n\r\f\v] ,还有很多其他字符,比如不同语言排版规则约定的不换行空格)。如果 ASCII 被设置,就只匹配 [ \t\n\r\f\v]

    • 对于8位(bytes)样式:

      匹配ASCII中的空白字符,就是 [ \t\n\r\f\v]

  • \w

    • 对于 Unicode (str) 样式:

      匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,也包括数字和下划线。如果设置了 ASCII 标志,就只匹配 [a-zA-Z0-9_]

    • 对于8位(bytes)样式:

      匹配ASCII字符中的数字和字母和下划线,就是 [a-zA-Z0-9_] 。如果设置了 [LOCALE] 标记,就匹配当前语言区域的数字和字母和下划线。

Re. 相关函数

  • re.``compile(pattern, flags=0)

    将正则表达式的样式编译为一个 正则表达式对象 (正则对象),可以用于匹配,通过这个对象的方法 [match()], [search()]以及其他如下描述。

    这个表达式的行为可以通过指定 标记 的值来改变。值可以是以下任意变量,可以通过位的OR操作来结合( | 操作符)。

    序列

    1
    2
    prog = re.compile(pattern)
    result = prog.match(string)

    等价于

    1
    result = re.match(pattern, string)

    如果需要多次使用这个正则表达式的话,使用 [re.compile()] 和保存这个正则对象以便复用,可以让程序更加高效。

    注解:通过 [re.compile()]编译后的样式,和模块级的函数会被缓存, 所以少数的正则表达式使用无需考虑编译的问题。

  • re.search(pattern, string, flags=0)

    扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 [匹配对象]。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。

  • re.match(pattern, string, flags=0)

    如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 [匹配对象]。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的

  • fullmatch(pattern, string, flags=0)

    如果整个 string 匹配到正则表达式样式,就返回一个相应的 [匹配对象] 。 否则就返回一个 None ;注意这跟零长度匹配是不同的。

  • split(pattern, string, maxsplit=0, flags=0)

    pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。

    • re.split()切割功能非常强大
    • 单字符切割
    • 两个字符以上切割需要放在 [ ] 中
    • 所有空白字符切割
    • 使用括号捕获分组,默认保留分割符
    • 不想保留分隔符,以(?:…)的形式指定
      image-20210817165955259
  • re.findall(pattern, string, flags=0)

    string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。

  • re.sub(pattern, repl, string, count=0, flags=0)

    返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 stringrepl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,\n 会被转换为一个换行符,\r 会被转换为一个回车附,依此类推。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。 其他未知转义序列例如 \& 会保持原样。 向后引用像是 \6 会用样式中第 6 组所匹配到的子字符串来替换。 例如

上课笔记&重点

1
2
txt = 'Column 1 Column 2 Column 3 Column 3546   Column 3s   '
re.findall('Column [0-9]+ *', txt)

1
re.search('(Column [0-9]+ *)*', txt)

image-20210817172359823

1
re.findall('(Column [0-9]+ *)+', txt)

上课示例

1
2
3
4
5
6
7
8
9
10
import re
txt = "Tie best singer ever is Jay Chou,The ticket price for his concert is $100"

x = re.findall('[A-Z]', txt)

if(x):
print('find success', x)

x = re.search('a\^b', 'sdasd a^b sab')
print(x)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
txt2 = 'The best thing is  love, the other is hate'

m = re.findall('the', txt2)
print(m)

m = re.findall('[tT]he', txt2)
print(m)

m = re.findall('\\b[tT]he\\b', txt2)
print(m)

m = re.findall(r'\b[tT]he\b', txt2)
print(m)

m = re.findall('[^a-zA-Z][tT]he[^a-zA-Z]', txt2)
print(m)

m = re.findall(r'[^a-zA-Z][tT]he[^a-zA-Z]', txt2)
print(m)

1
2
3
txt3 = '025-12345678 #这是一个南京电话号码'
n = re.sub('#.*$','', txt3)
print(n)

1
2
3
4
5
6
7
8
9
10
11
12
txt4 = 'guppy guppies'
d = re.findall('guppy|ies', txt4)
print(d)

d = re.findall('gupp(y|ies)', txt4)
print(d) #显示最优先匹配

d = re.match('gupp(y|ies)', txt4)
print(d)

d = re.findall('guppy|guppies', txt4)
print(d) #显示最优先匹配

1
2
3
txt4 = 'once upon a time'
l = re.match('[a-z]*', txt4)
print(l)

Finate State Automata

本文作者:Smurf
本文链接:http://example.com/2021/08/15/nlp%20learning/Chapter1_regularexpressions/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可