- 前言
- 一、控制台获取输入
-
- [1.1 字符串输入](#1.1 字符串输入)
- [1.2 整数输入](#1.2 整数输入)
- [1.3 浮点数输入](#1.3 浮点数输入)
- [1.4 布尔值输入](#1.4 布尔值输入)
- [1.5 列表输入](#1.5 列表输入)
- [1.6 汇总](#1.6 汇总)
- 二、正则表达式
-
- [2.1 匹配数字](#2.1 匹配数字)
- [2.2 模式检查](#2.2 模式检查)
- [2.3 替换字符](#2.3 替换字符)
- [2.4 切分字符串](#2.4 切分字符串)
- [2.5 搜索并提取匹配的部分](#2.5 搜索并提取匹配的部分)
- [2.6 使用捕获组提取匹配的部分](#2.6 使用捕获组提取匹配的部分)
- [2.7 非贪婪匹配](#2.7 非贪婪匹配)
- [2.8 忽略大小写匹配](#2.8 忽略大小写匹配)
- [2.9 使用预定义字符类](#2.9 使用预定义字符类)
- [2.10 自定义字符类](#2.10 自定义字符类)
- [2.11 零宽断言](#2.11 零宽断言)
- [2.12 多行模式](#2.12 多行模式)
- [2.13 嵌入式修饰符](#2.13 嵌入式修饰符)
- [2.14 替换时使用回调函数](#2.14 替换时使用回调函数)
- [2.15 非捕获组](#2.15 非捕获组)
- [2.16 前向引用(匹配重复子字符串)](#2.16 前向引用(匹配重复子字符串))
- [2.17 替换中使用命名分组引用](#2.17 替换中使用命名分组引用)
- [2.18 回溯引用](#2.18 回溯引用)
- [2.19 负向前向引用](#2.19 负向前向引用)
- [2.20 嵌入条件匹配](#2.20 嵌入条件匹配)
- [2.21 后向引用断言](#2.21 后向引用断言)
- [2.22 零宽负向断言](#2.22 零宽负向断言)
- [2.23 转义序列匹配非打印字符](#2.23 转义序列匹配非打印字符)
- [2.24 贪婪与非贪婪匹配](#2.24 贪婪与非贪婪匹配)
- [2.25 汇总](#2.25 汇总)
前言
在Python编程中,控制台输入和正则表达式是两个重要而实用的概念。掌握这两个技巧可以帮助我们更灵活地处理用户输入以及对文本进行复杂的匹配和处理。本文中将详细介绍Python中如何通过控制台获取用户输入以及如何使用正则表达式进行文本处理。深入探讨输入类型转换、异常处理、多个输入值的存储等方面,并分享一些常见的正则表达式用法,如匹配数字、替换字符串、提取模式内容等。
一、控制台获取输入
1.1 字符串输入
python
# 输入字符串并赋值给变量str1:
str1 = input("请输入一个字符串: ")
1.2 整数输入
python
# 输入整数并赋值给变量count:
count = int(input("请输入一个整数: "))
1.3 浮点数输入
python
# 输入布尔值(True/False)并赋值给变量is_true:
is_true = bool(input("请输入一个布尔值(True/False): "))
1.4 布尔值输入
python
# 输入字符串并赋值给变量str1:
str1 = input("请输入一个字符串: ")
请注意,bool()函数将任何非空字符串解释为True,空字符串解释为False。
1.5 列表输入
python
# 输入多个数字以空格分隔,并将它们作为列表存储在变量list1中:
list1 = input("请输入多个数字(以空格分隔): ").split()
list1 = [int(num) for num in list1] # 将输入的数字转换为整数类型
print(list1)
这里使用了split()方法将输入的字符串切分成一个字符串列表,并使用列表推导式将字符串转换为整数类型。
python
# 输入多个字符串以逗号分隔,并将它们作为列表存储在变量str_list中:
str_list = input("请输入多个字符串(以逗号分隔): ").split(',')
这里使用了split()方法将输入的字符串切分成一个字符串列表,以逗号为分隔符。
1.6 汇总
python
# 在Python中,可以使用input()函数从控制台获取用户的输入。然后,根据需要进行类型转换和赋值。下面是一些示例:
# 输入字符串并赋值给变量str1:
str1 = input("请输入一个字符串: ")
# 输入整数并赋值给变量count:
count = int(input("请输入一个整数: "))
# 输入浮点数并赋值给变量float_num:
float_num = float(input("请输入一个浮点数: "))
# 输入布尔值(True/False)并赋值给变量is_true:
is_true = bool(input("请输入一个布尔值(True/False): "))
# 请注意,bool()函数将任何非空字符串解释为True,空字符串解释为False。
# 输入多个数字以空格分隔,并将它们作为列表存储在变量list1中:
list1 = input("请输入多个数字(以空格分隔): ").split()
list1 = [int(num) for num in list1] # 将输入的数字转换为整数类型
print(list1)
# 这里使用了split()方法将输入的字符串切分成一个字符串列表,并使用列表推导式将字符串转换为整数类型。
# 输入多个字符串以逗号分隔,并将它们作为列表存储在变量str_list中:
str_list = input("请输入多个字符串(以逗号分隔): ").split(',')
# 这里使用了split()方法将输入的字符串切分成一个字符串列表,以逗号为分隔符。
# 记住,在处理用户输入时要小心异常情况,例如错误的类型转换或无效的输入。
二、正则表达式
2.1 匹配数字
python
# 导入re模块:
import re
# 匹配字符串中的数字:
pattern = r'\d+' # 匹配连续的数字
text = "abc123def456ghi"
result = re.findall(pattern, text)
print(result) # 输出: ['123', '456']
2.2 模式检查
python
# 检查字符串是否符合特定的模式:
pattern = r'^[A-Za-z0-9]+$' # 检查是否只包含字母和数字
text = "abc123"
result = re.match(pattern, text)
if result:
print("字符串符合要求")
else:
print("字符串不符合要求")
2.3 替换字符
python
# 替换字符串中的部分内容:
pattern = r'\s+' # 匹配连续的空格
text = "Hello World"
new_text = re.sub(pattern, ' ', text) #表示把多个空格替换成一个空格
print(new_text) # 输出: "Hello World"
2.4 切分字符串
python
# 切分字符串:
pattern = r'[,\s]+' # 匹配逗号或空格
text = "apple,banana,orange"
result = re.split(pattern, text)
print(result) # 输出: ['apple', 'banana', 'orange']
2.5 搜索并提取匹配的部分
python
# 搜索并提取匹配的部分:
pattern = r'\d{3}-\d{4}-\d{4}' # 匹配电话号码的模式
text = "我的电话号码是:123-4567-8901"
result = re.search(pattern, text)
if result:
print(result.group()) # 输出: '123-4567-8901'
注意: re.search() 与re.match()返回第一个匹配项,与 re.search() 不同的是,re.match() 方法只匹配字符串的开头部分。因此,如果需要输出所有匹配项,应该使用 re.findall() 方法。
2.6 使用捕获组提取匹配的部分
python
# 使用捕获组提取匹配的部分:
pattern = r'(\d{3})-(\d{4})-(\d{4})' # 匹配电话号码的模式,并使用捕获组分别提取区号、中间号和尾号
text = "我的电话号码是:123-4567-8901"
result = re.search(pattern, text)
if result:
area_code = result.group(1)
middle_number = result.group(2)
last_number = result.group(3)
print(area_code, middle_number, last_number) # 输出: '123', '4567', '8901'
2.7 非贪婪匹配
python
# 非贪婪匹配(匹配最短的字符串):
pattern = r'<.*?>' # 非贪婪匹配尖括号之间的内容
text = "<p>这是一个段落</p><p>另一个段落</p>"
result = re.findall(pattern, text)
print(result) # 输出: ['<p>', '</p>', '<p>', '</p>']
2.8 忽略大小写匹配
python
# 忽略大小写匹配:
pattern = r'python'
text = "Python is a programming language"
result = re.findall(pattern, text, re.IGNORECASE)
print(result) # 输出: ['Python']
2.9 使用预定义字符类
python
# 使用预定义字符类:
pattern = r'\w+' # 匹配字母、数字和下划线
text = "Hello 123_world*&"
result = re.findall(pattern, text)
print(result) # 输出: ['Hello', '123_world']
2.10 自定义字符类
python
# 自定义字符类:
pattern = r'[aeiou]' # 匹配元音字母
text = "apple orange banana"
result = re.findall(pattern, text)
print(result) # 输出: ['a', 'e', 'o', 'a', 'a']
2.11 零宽断言
python
# 零宽断言(Lookahead/Lookbehind):零宽断言允许你在匹配字符串时指定一些条件,但不会将这些条件包含在最终的匹配结果中。例如,可以使用正向零宽断言来匹配前面是特定模式的文本:
pattern = r'\w+(?=ing)' # 匹配以 "ing" 结尾的单词的前面部分
text = "running jumping swimming"
result = re.findall(pattern, text)
print(result) # 输出: ['runn', 'jump']
2.12 多行模式
python
# 多行模式:使用多行模式可以处理多行文本,其中 ^ 和 $ 元字符匹配每行的开头和结尾。通过传递 re.MULTILINE 标志给 re.compile() 函数或使用 re.M 缩写标志来启用多行模式:
pattern = r'^\d+$' # 匹配只包含数字的行
text = "123\nabc\n456\n789"
result = re.findall(pattern, text, re.MULTILINE)
print(result) # 输出: ['123', '456', '789']
2.13 嵌入式修饰符
python
# 嵌入式修饰符:可以在正则表达式中使用嵌入式修饰符来改变匹配的行为。例如,使用 (?i) 来忽略大小写匹配:
pattern = r'(?i)python' # 忽略大小写匹配 "python"
text = "Python is a programming language"
result = re.findall(pattern, text)
print(result) # 输出: ['Python']
2.14 替换时使用回调函数
python
# 替换时使用回调函数:使用 re.sub() 函数进行替换时,可以传递一个回调函数来处理每个匹配项,并返回替换后的结果。这允许你根据匹配到的内容动态生成替换值:
def replace_func(match):
num = int(match.group(0))
return str(num*2)
pattern = r'\d+'
text = "123423w 2w 3yui 4 5"
result = re.sub(pattern, replace_func, text)
print(result) #246846w 4w 6yui 8 10
2.15 非捕获组
python
# 非捕获组:有时你可能需要使用括号进行分组,但不需要捕获该组的内容。在这种情况下,可以使用非捕获组 (?:...):
pattern = r'(?:https?://)?(www\.[A-Za-z]+\.[A-Za-z]+)'
text = "Visit my website at www.example.com"
result = re.findall(pattern, text)
print(result) # 输出: ['www.example.com']
2.16 前向引用(匹配重复子字符串)
python
# 前向引用:前向引用允许你引用之前已经匹配的内容。这在匹配重复的子字符串时非常有用:
pattern = r'(\w+)\s+\1' # 匹配重复的单词
text = "apple apple banana banana cherry cherry"
result = re.findall(pattern, text)
print(result) # 输出: ['apple', 'banana', 'cherry']
2.17 替换中使用命名分组引用
python
# 替换中使用命名分组引用:可以使用命名分组 (P<name>...) 来指定一个命名的捕获组,并在替换时使用 \\g<name> 引用该组的内容:
pattern = r'(?P<first>\d+)\s+(?P<second>\d+)'
text = "10 20"
result = re.sub(pattern, '\\g<second> \\g<first>', text)
print(result) # 输出: "20 10"
2.18 回溯引用
python
# 回溯引用:使用回溯引用可以匹配重复的模式,并在替换时保留其中一个副本:
pattern = r'(\d+)-\1' # 匹配连续重复的数字,例如 "22-22"
text = "11-11 22-22 33-33"
result = re.findall(pattern, text)
print(result) # 输出: ['11', '22', '33']
2.19 负向前向引用
python
# 负向前向引用:负向前向引用允许你指定一个模式,该模式不能在当前位置之后出现。可以使用 (?!...) 来表示负向前向引用:
pattern = r'\b(?!un)\w+\b' # 匹配不以 "un" 开头的单词
text = "happy unhappy apple banana"
result = re.findall(pattern, text)
print(result) # 输出: ['happy', 'apple', 'banana']
2.20 嵌入条件匹配
python
# 嵌入条件匹配:使用 (?if:...) 来实现条件匹配。可以根据条件选择不同的模式进行匹配:
pattern = r'(?i)(?:(?<=Mr\.)|(?<=Ms\.)|(?<=Mrs\.))\s\w+'
text = "Hello Mr. Smith, Ms. Johnson, and Mrs. Davis"
result = re.findall(pattern, text)
print(result) # 输出: ['Smith', 'Johnson', 'Davis']
2.21 后向引用断言
python
# 后向引用断言:使用 (?<=(...)) 来实现后向引用断言,即在匹配的位置之前必须满足某个条件:
pattern = r'\b(\w+)\b(?<=(ing))' # 匹配以 "ing" 结尾的单词中的前面部分
text = "running jumping swimming"
result = re.findall(pattern, text)
print(result) # 输出: ['runn', 'jump']
2.22 零宽负向断言
python
# 零宽负向断言:使用 (?<!...) 来实现零宽负向断言,即在当前位置之前不能满足某个条件:
pattern = r'(?<!un)\b\w+\b' # 匹配不以 "un" 开头的单词
text = "happy unhappy apple banana"
result = re.findall(pattern, text)
print(result) # 输出: ['happy', 'apple', 'banana']
2.23 转义序列匹配非打印字符
python
# 非打印字符:可以使用转义序列来匹配非打印字符,如制表符 \t、换行符 \n 等:
pattern = r'abc\tdef\nghi'
text = "abc\tdef\nghi"
result = re.findall(pattern, text)
print(result) # 输出: ['abc\tdef\nghi']
2.24 贪婪与非贪婪匹配
python
# 贪婪与非贪婪匹配:在重复模式中,默认情况下是贪婪匹配,尽可能多地匹配。但可以使用 ? 来指定非贪婪匹配,尽可能少地匹配:
s = "aaaabaaaa"
pattern = r'a.*a' # 贪婪匹配模式
match = re.search(pattern, s)
if match:
print(match.group()) # 输出:'aaaabaaaa'
s = "aaaabaaaa"
pattern = r'a.*?a' # 非贪婪匹配模式
match = re.search(pattern, s)
if match:
print(match.group()) # 输出:'aaa'
2.25 汇总
python
# 在Python中,可以使用正则表达式模块re来进行字符串的匹配和处理。下面是一些常见的正则处理示例:
# 导入re模块:
import re
# 匹配字符串中的数字:
pattern = r'\d+' # 匹配连续的数字
text = "abc123def456ghi"
result = re.findall(pattern, text)
print(result) # 输出: ['123', '456']
# 检查字符串是否符合特定的模式:
pattern = r'^[A-Za-z0-9]+$' # 检查是否只包含字母和数字
text = "abc123"
result = re.match(pattern, text)
if result:
print("字符串符合要求")
else:
print("字符串不符合要求")
# 替换字符串中的部分内容:
pattern = r'\s+' # 匹配连续的空格
text = "Hello World"
new_text = re.sub(pattern, ' ', text) #表示把多个空格替换成一个空格
print(new_text) # 输出: "Hello World"
# 切分字符串:
pattern = r'[,\s]+' # 匹配逗号或空格
text = "apple,banana,orange"
result = re.split(pattern, text)
print(result) # 输出: ['apple', 'banana', 'orange']
# 搜索并提取匹配的部分:
pattern = r'\d{3}-\d{4}-\d{4}' # 匹配电话号码的模式
text = "我的电话号码是:123-4567-8901"
result = re.search(pattern, text)
if result:
print(result.group()) # 输出: '123-4567-8901'
# 使用捕获组提取匹配的部分:
pattern = r'(\d{3})-(\d{4})-(\d{4})' # 匹配电话号码的模式,并使用捕获组分别提取区号、中间号和尾号
text = "我的电话号码是:123-4567-8901"
result = re.search(pattern, text)
if result:
area_code = result.group(1)
middle_number = result.group(2)
last_number = result.group(3)
print(area_code, middle_number, last_number) # 输出: '123', '4567', '8901'
# 非贪婪匹配(匹配最短的字符串):
pattern = r'<.*?>' # 非贪婪匹配尖括号之间的内容
text = "<p>这是一个段落</p><p>另一个段落</p>"
result = re.findall(pattern, text)
print(result) # 输出: ['<p>', '</p>', '<p>', '</p>']
# 忽略大小写匹配:
pattern = r'python'
text = "Python is a programming language"
result = re.findall(pattern, text, re.IGNORECASE)
print(result) # 输出: ['Python']
# 使用预定义字符类:
pattern = r'\w+' # 匹配字母、数字和下划线
text = "Hello 123_world*&"
result = re.findall(pattern, text)
print(result) # 输出: ['Hello', '123_world']
# 自定义字符类:
pattern = r'[aeiou]' # 匹配元音字母
text = "apple orange banana"
result = re.findall(pattern, text)
print(result) # 输出: ['a', 'e', 'o', 'a', 'a']
# 零宽断言(Lookahead/Lookbehind):零宽断言允许你在匹配字符串时指定一些条件,但不会将这些条件包含在最终的匹配结果中。例如,可以使用正向零宽断言来匹配前面是特定模式的文本:
pattern = r'\w+(?=ing)' # 匹配以 "ing" 结尾的单词的前面部分
text = "running jumping swimming"
result = re.findall(pattern, text)
print(result) # 输出: ['runn', 'jump']
# 多行模式:使用多行模式可以处理多行文本,其中 ^ 和 $ 元字符匹配每行的开头和结尾。通过传递 re.MULTILINE 标志给 re.compile() 函数或使用 re.M 缩写标志来启用多行模式:
pattern = r'^\d+$' # 匹配只包含数字的行
text = "123\nabc\n456\n789"
result = re.findall(pattern, text, re.MULTILINE)
print(result) # 输出: ['123', '456', '789']
# 嵌入式修饰符:可以在正则表达式中使用嵌入式修饰符来改变匹配的行为。例如,使用 (?i) 来忽略大小写匹配:
pattern = r'(?i)python' # 忽略大小写匹配 "python"
text = "Python is a programming language"
result = re.findall(pattern, text)
print(result) # 输出: ['Python']
# 替换时使用回调函数:使用 re.sub() 函数进行替换时,可以传递一个回调函数来处理每个匹配项,并返回替换后的结果。这允许你根据匹配到的内容动态生成替换值:
def replace_func(match):
num = int(match.group(0))
return str(num*2)
pattern = r'\d+'
text = "123423w 2w 3yui 4 5"
result = re.sub(pattern, replace_func, text)
print(result) #246846w 4w 6yui 8 10
# 非捕获组:有时你可能需要使用括号进行分组,但不需要捕获该组的内容。在这种情况下,可以使用非捕获组 (?:...):
pattern = r'(?:https?://)?(www\.[A-Za-z]+\.[A-Za-z]+)'
text = "Visit my website at www.example.com"
result = re.findall(pattern, text)
print(result) # 输出: ['www.example.com']
# 前向引用:前向引用允许你引用之前已经匹配的内容。这在匹配重复的子字符串时非常有用:
pattern = r'(\w+)\s+\1' # 匹配重复的单词
text = "apple apple banana banana cherry cherry"
result = re.findall(pattern, text)
print(result) # 输出: ['apple', 'banana', 'cherry']
# 替换中使用命名分组引用:可以使用命名分组 (P<name>...) 来指定一个命名的捕获组,并在替换时使用 \\g<name> 引用该组的内容:
pattern = r'(?P<first>\d+)\s+(?P<second>\d+)'
text = "10 20"
result = re.sub(pattern, '\\g<second> \\g<first>', text)
print(result) # 输出: "20 10"
# 回溯引用:使用回溯引用可以匹配重复的模式,并在替换时保留其中一个副本:
pattern = r'(\d+)-\1' # 匹配连续重复的数字,例如 "22-22"
text = "11-11 22-22 33-33"
result = re.findall(pattern, text)
print(result) # 输出: ['11', '22', '33']
# 负向前向引用:负向前向引用允许你指定一个模式,该模式不能在当前位置之后出现。可以使用 (?!...) 来表示负向前向引用:
pattern = r'\b(?!un)\w+\b' # 匹配不以 "un" 开头的单词
text = "happy unhappy apple banana"
result = re.findall(pattern, text)
print(result) # 输出: ['happy', 'apple', 'banana']
# 嵌入条件匹配:使用 (?if:...) 来实现条件匹配。可以根据条件选择不同的模式进行匹配:
pattern = r'(?i)(?:(?<=Mr\.)|(?<=Ms\.)|(?<=Mrs\.))\s\w+'
text = "Hello Mr. Smith, Ms. Johnson, and Mrs. Davis"
result = re.findall(pattern, text)
print(result) # 输出: ['Smith', 'Johnson', 'Davis']
# 后向引用断言:使用 (?<=(...)) 来实现后向引用断言,即在匹配的位置之前必须满足某个条件:
pattern = r'\b(\w+)\b(?<=(ing))' # 匹配以 "ing" 结尾的单词中的前面部分
text = "running jumping swimming"
result = re.findall(pattern, text)
print(result) # 输出: ['runn', 'jump']
# 零宽负向断言:使用 (?<!...) 来实现零宽负向断言,即在当前位置之前不能满足某个条件:
pattern = r'(?<!un)\b\w+\b' # 匹配不以 "un" 开头的单词
text = "happy unhappy apple banana"
result = re.findall(pattern, text)
print(result) # 输出: ['happy', 'apple', 'banana']
# 非打印字符:可以使用转义序列来匹配非打印字符,如制表符 \t、换行符 \n 等:
pattern = r'abc\tdef\nghi'
text = "abc\tdef\nghi"
result = re.findall(pattern, text)
print(result) # 输出: ['abc\tdef\nghi']
# 贪婪与非贪婪匹配:在重复模式中,默认情况下是贪婪匹配,尽可能多地匹配。但可以使用 ? 来指定非贪婪匹配,尽可能少地匹配:
s = "aaaabaaaa"
pattern = r'a.*a' # 贪婪匹配模式
match = re.search(pattern, s)
if match:
print(match.group()) # 输出:'aaaabaaaa'
s = "aaaabaaaa"
pattern = r'a.*?a' # 非贪婪匹配模式
match = re.search(pattern, s)
if match:
print(match.group()) # 输出:'aaa'