在正则表达式中,+
、*
、和?
是三个常用的量词,分别用来指定前面元素的匹配次数:
+
表示匹配前面的元素一次或多次(至少一次,一次以上)。*
表示匹配前面的元素零次或多次(也可以是不出现,0次以上)。?
表示匹配前面的元素零次或一次(即元素是可选的,0次或1次)。
示例:
假设我们有文本字符串"The rain in Spain falls mainly in the plain."
,并且我们想要使用正则表达式来匹配不同的部分:
使用
+
量词:- 模式:
\w+
等效於[a-zA-Z0-9_] #大小寫字母以及下底線 - 说明:匹配一个或多个字母数字字符或下划线。
- 结果:匹配到’The’, ‘rain’, ‘in’, ‘Spain’, ‘falls’, ‘mainly’, ‘in’, ‘the’, ‘plain’。
- 模式:
使用
*
量词:- 模式:
ai*
- 说明:匹配’a’后面跟随零个或多个’i’。
- 结果:匹配到’ai’ 在”rain” 和 “Spain”中,以及’a’在”plain”中。
- 模式:
使用
?
量词:- 模式:
rai?n
- 说明:匹配’r’后面跟着一个可选的’i’,然后是’n’。
- 结果:匹配到”rain”和”ran”(如果”ran”出现在文本中)。
- 模式:
Python示例代码:
import re
text = "The rain in Spain falls mainly in the plain."
# 使用+
matches_plus = re.findall(r'\w+', text)
print("+:", matches_plus)
# 使用*
matches_star = re.findall(r'ai*', text)
print("*:", matches_star)
# 使用?
matches_question = re.findall(r'rai?n', text)
print("?:", matches_question)
輸出結果:
推薦hahow線上學習python: https://igrape.net/30afN
想要以空白切割字串 str.split(),
但是不想要切割到”degrees C”中的空白
因此需要使用正則表示法
.findall()
import re
# 假设的输入字符串
input_string = 'type="thermal" name="fleeting1" reading="100.000" units="degrees C" validity="valid" timestamp="1701343772.782743" devpath="/phys"'
# 使用re.findall提取键值对
matches: list = re.findall(r'(\w+)="([^"]*)"', input_string)
# 将matches列表转换为字典
data_dict = {key: value for key, value in matches}
print(data_dict)
輸出結果:
这段代码首先使用re.findall
方法与正则表达式(\w+)="([^"]*)"
来查找所有的键值对。这个正则表达式的意思是匹配一个或多个字母数字下划线(\w+
表示键),后面跟着等号和被双引号包围的任意字符("([^"]*)"
表示值),并忽略任何不符合这个模式的文本。
找到所有匹配后,它使用列表推导式将匹配结果转换为字典格式,其中每个键值对作为字典的一个条目。
这个方法可以有效地将你的字符串转换成字典,前提是字符串格式保持一致,且所有的值都用双引号包围。如果字符串格式有所不同,可能需要调整正则表达式来适应这些变化。
在正则表达式中,([^"]*)
是一个非常有用的模式,用于匹配任何不是双引号"
的字符序列。这个模式被封装在一对圆括号内,表示它是一个捕获组,可以从匹配的文本中提取出对应的部分。具体来说:
[^"]
:这部分是一个字符类,^
在字符类的开头表示取反,即匹配除了双引号之外的任何字符。*
:紧跟在字符类后面,表示匹配前面的字符(这里是除了双引号之外的任何字符)0次或多次。
当你问到([^"]*)?
时,?
被添加到整个捕获组的后面,这意味着整个捕获组是可选的。在正则表达式中,?
使得前面的元素(可以是单个字符、字符类、捕获组等)变成可选的,即这个元素可以出现0次或1次。因此:
([^"]*)
:可以匹配任意长度(包括零长度)的非双引号字符序列。([^"]*)?
:可以匹配同样的序列,但它也接受完全没有字符的情况。这意味着即使在双引号之间没有任何内容,这个表达式也能匹配成功。
这种模式通常用于解析带有可选值的键值对数据。例如,在解析HTML属性或类似于你提供的字符串格式时,如果某些键可能没有对应的值,使用([^"]*)?
可以确保这种情况下的匹配也能成功进行。
Python的re
(正则表达式)模块中,当你使用re.findall
函数与包含多个捕获组的正则表达式进行匹配时,re.findall
会自动将每个匹配的结果作为一个元组返回。每个捕获组的匹配结果会按照在正则表达式中出现的顺序被放入这个元组中。
在你的例子中,正则表达式r'(\w+)="([^"]*)"'
包含两个捕获组:
- 第一个捕获组
(\w+)
用来匹配键名,即等号前面的单词(由字母、数字或下划线组成)。 - 第二个捕获组
"([^"]*)"
用来匹配双引号内的值,即等号后面的字符串(可以包含任何字符,除了双引号本身)。
因此,当re.findall
使用这个正则表达式在字符串中查找匹配项时,它会为每个匹配的键值对生成一个元组,元组的第一个元素是键名,第二个元素是对应的值。这就是为什么matches
列表中的每个项都是一个元组的原因。
这种行为使得将匹配的结果直接转换成字典变得非常方便,正如你已经看到的,通过简单地遍历matches
列表并将元组解包为键和值,就可以构建一个字典,其中每个键都映射到相应的值。
推薦hahow線上學習python: https://igrape.net/30afN
近期留言