awk正则表达式是贪婪匹配,以及复习Python正则表达式re

举个例子:

对/etc/passwd的第20行到第25行,当指定 [*:/]+ 作为分隔符时会贪婪匹配  :*:  与 :/ 为一个间隔符,而在指定 [*:/] 作为分割符时只会分别将 :*: 匹配成3个分隔符, :/  匹配成2个分隔符。

(venv_mac)  ⚙ haypin@HaypinsMBP  ~/PycProj  awk -F ':' '{if (NR>=20 && NR<=25) print $0}' /etc/passwd
_scsd:*:31:31:Service Configuration Service:/var/empty:/usr/bin/false
_ces:*:32:32:Certificate Enrollment Service:/var/empty:/usr/bin/false
_appstore:*:33:33:Mac App Store Service:/var/db/appstore:/usr/bin/false
_mcxalr:*:54:54:MCX AppLaunch:/var/empty:/usr/bin/false
_appleevents:*:55:55:AppleEvents Daemon:/var/empty:/usr/bin/false
_geod:*:56:56:Geo Services Daemon:/var/db/geod:/usr/bin/false
(venv_mac)  ⚙ haypin@HaypinsMBP  ~/PycProj  awk -F '[*:/]' '{if (NR>=20 && NR<=25) print $1" "$2" "$4" "$5}' /etc/passwd
_scsd  31 31
_ces  32 32
_appstore  33 33
_mcxalr  54 54
_appleevents  55 55
_geod  56 56
(venv_mac)  ⚙ haypin@HaypinsMBP  ~/PycProj  awk -F '[*:/]+' '{if (NR>=20 && NR<=25) print $1" "$2" "$4" "$5}' /etc/passwd
_scsd 31 Service Configuration Service var
_ces 32 Certificate Enrollment Service var
_appstore 33 Mac App Store Service var
_mcxalr 54 MCX AppLaunch var
_appleevents 55 AppleEvents Daemon var
_geod 56 Geo Services Daemon var

Python正则表达式re

官网介绍:https://docs.python.org/zh-cn/3/library/re.html

模式和被搜索的字符串既可以是 Unicode 字符串 (str) ,也可以是8位字节串 (bytes)。 但是,Unicode 字符串与 8 位字节串不能混用:也就是说,不能用字节串模式匹配 Unicode 字符串,反之亦然;同理,替换操作时,替换字符串的类型也必须与所用的模式和搜索字符串的类型一致。

正则表达式用反斜杠字符 ('\') 表示特殊形式,或是允许在使用特殊字符时,不引发它们的特殊含义。 这与 Python 的字符串字面值中对相同字符出于相同目的的用法产生冲突;例如,要匹配一个反斜杠字面值,用户可能必须写成 '\\\\' 来作为模式字符串,因为正则表达式必须为 \\,而每个反斜杠在普通 Python 字符串字面值中又必须表示为 \\。 

解决办法是对于正则表达式样式使用 Python 的原始字符串表示法;在带有 'r' 前缀的字符串字面值中,反斜杠不必做任何特殊处理(直接作为字符串对象)。 因此 r"\n" 表示包含 '\' 和 'n' 两个字符的字符串,而 "\n" 则表示只包含一个换行符的字符串。 样式在 Python 代码中通常都使用原始字符串表示法。

这句话的理解:

在Shell中输入的正则表达式是“原生”的正则表达式字符串,直接当作正则表达式用,所以匹配字面的\反斜杠字符时直接输入正则表达式 '\\'

(venv_mac)  ⚙ haypin@HaypinsMBP  ~/PycProj  grep -w '\\' test.txt
\
(venv_mac)  ⚙ haypin@HaypinsMBP  ~/PycProj  cat test.txt
ab
aa
abc
\
(venv_mac)  ⚙ haypin@HaypinsMBP  ~/PycProj  grep -w '\\' test.txt
\

而Python脚本对reg = re.compile( '\\\\' )代码行,首先按 # -*- coding: utf-8 -*- 编码进行字符串字面值——>字符串的解析,字符串字面值 '\\\\' 被解析成字符串 '\\' ,这里发生了对 \ 的转义,然后执行字符串——>正则表达式的解析,字符串 '\\' 被解析成正则表达式 r'\\' ,这里只发生了对 \ 的转义。

>>> import re
>>> reg = re.compile('\\\\')
>>> res = reg.match('\\')
>>> res.group(0)
'\\'
>>> reg2 = re.compile(r'\\')
>>> res2 = reg2.match('\\')
>>> res2.group(0)
'\\'

所以Python中正则表达式使用 reg = re.compile(r'\\'),不再进行(跳过)字符串字面值——>字符串的转义,直接将字符串字面值作为字符串,然后进行字符串——>正则表达式的转义。

Python正则表达式官方文档:

\

转义特殊字符(允许你匹配 '*''?', 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。

如果你没有使用原始字符串( r'raw' )来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。

re模块的正则表达式类re.Pattern的构造函数re.compile(pattern,flags)的flags默认或了re.LOCALE,从而可以根据要匹配的字符串内容的语言判断英文语境下的单词、中文语境下的单词:

>>> reg = re.compile(r'\w+')
>>> print(mystr)
张3_
>>> res = reg.search(mystr)
>>> res.group(0)
'张3_'
>>> print(mystr2)
 apple_
>>> res = reg.search(mystr2)
>>> res.group(0)
'apple_'
>>> reg2 = re.compile(r'我+')
>>> mystr2 = '我我我我'
>>> res = reg2.search(mystr2)
>>> res.group(0)
'我我我我'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值