Python正则表达式

正则表达式

正则表达式(regularexpression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

1. 普通字符:

字符描述
[ABC]匹配[…]中的字符
[^ABC]匹配除[…]中的字符
[A-Z]匹配[…]区间中的字符
\s匹配任意空白字符(包括空格、制表符、换行等)
\S匹配任意非空字符
\d匹配任意数字
\D匹配任意非数字
\w匹配包括下划线的任意单词字符 => [A-Za-z0-9
\W匹配任意非单词字符 => [^A-Za-z90-9]
\Xn匹配n,其中n为十六进制转义值 例如"\x41"匹配A
\Un匹配n,其中n是一个用四个十六进制数字表示的Unicode字符

2. 非打印字符

字符描述
\cx匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符
\f匹配一个换页符
\n匹配一个换行符
\r匹配一个回车符
\t匹配一个制表符
\v匹配一个垂直制表符

3. 特殊字符

字符描述
$匹配输入字符串结尾位置
()标记子表达式
*匹配前面子表达式零次或多次
+匹配前面的子表达式一次或多次
.匹配除换行符\n之外的任何字符
[]匹配中括号表达式限定字符
?匹配前面子表达式零次或一次,或指明一个非贪婪限定符
\转义字符
^匹配输入字符串的开始位置,方括号表达式中表示不接受该方括号表达式中的字符集合
{}标记限定符表达式
\指明两项之间的一个选择
.*匹配任意长度的任意字符

4. 限定符

字符描述
*匹配前面子表达式零次或多次
+匹配前面的子表达式一次或多次
?匹配前面子表达式零次或一次,或指明一个非贪婪限定符
{n}n 是一个非负整数,确定匹配 n 次
{n,n 是一个非负整数,至少匹配 n 次
{n,m}m 和 n 均为非负证书,最少匹配 n 次且最多匹配 m次

5. 定位符

字符描述
^匹配输入字符开始位置
$匹配输入字符结尾位置
\b匹配一个单词边界,即字与空格间的位置
\B匹配一个非单词边界

6. 贪婪匹配和非贪婪匹配

名称概念
贪婪匹配在整个表达式匹配成功前提下,尽可能多的匹配
非贪婪匹配在整个表达式匹配成功的前提下,尽可能少的匹配
* 和 + 和 ?都是贪婪的,尽可能匹配多的字符,只要在它们后面加上一个 ? 就可以实现非贪婪匹配
?非贪婪限定符

7. ? 的组合用法

字符描述
?=exp1(?=exp2):正向肯定检查,查找exp1后面exp2的exp1
?<=(?<=exp2)exp1:反向肯定检查,查找exp1前面是exp2的exp1
?!exp1(?!exp2):正向否定查找exp1后面不是exp2的exp1
?<!(?<!exp2)exp1:反向否定查找exp1前面不是exp2的exp1
(?:pattern)非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用
(pattern)获取匹配,匹配pattern并获取匹配结果

Python re库

基本用法描述
re.I忽略大小写
re.M多行模式,改变’^‘和’$‘的行为
re.S点任意匹配模式,改变’.'的行为
re.L使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
re.U使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
re.X详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释
函数描述
re.findall()搜索所有满足条件的字符串
re.match()从第一个字符开始匹配模式
re.search()搜索第一个满足条件的字符串,查找到第一个停止
re.sub()替换满足条件的字符串
re.compile()创建模式对象,可以实现更有效率的匹配
re.escape(string)把string中,除了字母和数字以外的字符,都加上反斜杠
  1. pattern是用compile创建的模式对象。如下:
import re
some_text = 'a,b,,,,c d'
reObj = re.compile('[, ]+')
reObj.split(some_text)
['a', 'b', 'c', 'd']
  1. 不使用re.compile在进行search,match等操作前不适用compile函数,会导致重复使用模式时,需要对模式进行重复的转换。降低匹配速度。而此种方法的调用方式,更为直观。如下:
import re
some_text = 'a,b,,,,c d'
re.split('[, ]+',some_text)
['a', 'b', 'c', 'd']

练习

1. 将masscan扫描结果格式化存入表格中:

  1. 测试数据如下:
# masscan
Discovered open port 6667/tcp on 10.10.10.254
Discovered open port 139/tcp on 10.10.10.142
Discovered open port 512/tcp on 10.10.10.254
Discovered open port 5040/tcp on 10.10.10.142
Discovered open port 6000/tcp on 10.10.10.254
Discovered open port 51849/tcp on 10.10.10.254
Discovered open port 5357/tcp on 10.10.10.142
Discovered open port 3306/tcp on 10.10.10.142
Discovered open port 1099/tcp on 10.10.10.254
Discovered open port 6697/tcp on 10.10.10.254
Discovered open port 3306/tcp on 10.10.10.254
Discovered open port 49666/tcp on 10.10.10.142
Discovered open port 44453/tcp on 10.10.10.254
Discovered open port 49674/tcp on 10.10.10.142
Discovered open port 514/tcp on 10.10.10.254
Discovered open port 49664/tcp on 10.10.10.142
Discovered open port 80/tcp on 10.10.10.142
Discovered open port 8787/tcp on 10.10.10.254
Discovered open port 5900/tcp on 10.10.10.254
Discovered open port 23/tcp on 10.10.10.254
Discovered open port 37692/tcp on 10.10.10.254
Discovered open port 5432/tcp on 10.10.10.254
Discovered open port 49665/tcp on 10.10.10.142
Discovered open port 8009/tcp on 10.10.10.254
Discovered open port 8180/tcp on 10.10.10.254
Discovered open port 25/tcp on 10.10.10.254
Discovered open port 1433/tcp on 10.10.10.142
Discovered open port 513/tcp on 10.10.10.254
Discovered open port 135/tcp on 10.10.10.142
Discovered open port 445/tcp on 10.10.10.142
Discovered open port 2049/tcp on 10.10.10.254
Discovered open port 22/tcp on 10.10.10.254
Discovered open port 80/tcp on 10.10.10.254
Discovered open port 3632/tcp on 10.10.10.254
Discovered open port 53/tcp on 10.10.10.2
Discovered open port 49669/tcp on 10.10.10.142
Discovered open port 50165/tcp on 10.10.10.254
Discovered open port 49667/tcp on 10.10.10.142
Discovered open port 49680/tcp on 10.10.10.142
Discovered open port 1524/tcp on 10.10.10.254
Discovered open port 53/tcp on 10.10.10.254
Discovered open port 21/tcp on 10.10.10.254
Discovered open port 111/tcp on 10.10.10.254
Discovered open port 2121/tcp on 10.10.10.254
Discovered open port 445/tcp on 10.10.10.254
Discovered open port 80/tcp on 10.10.10.143
Discovered open port 3306/tcp on 10.10.10.143
Discovered open port 49666/tcp on 192.168.1.109
Discovered open port 139/tcp on 192.168.1.109
Discovered open port 443/tcp on 192.168.1.109
Discovered open port 445/tcp on 192.168.1.109
Discovered open port 5040/tcp on 192.168.1.109
Discovered open port 912/tcp on 192.168.1.109
Discovered open port 49668/tcp on 192.168.1.109
Discovered open port 49670/tcp on 192.168.1.109
Discovered open port 3389/tcp on 192.168.1.109
Discovered open port 49665/tcp on 192.168.1.109
Discovered open port 5357/tcp on 192.168.1.109
Discovered open port 49664/tcp on 192.168.1.109
Discovered open port 49671/tcp on 192.168.1.109
  1. 执行代码如下:
import re
import csv
import pandas as pd

if __name__ == '__main__':
    with open("masscan_data.csv","w", newline='') as datafile:
        writer = csv.writer(datafile)
        writer.writerow(["Address", 'Protocol', 'Port'])
        results = []
        with open("test.txt", "r") as file:
            lines = file.readlines()
            for line in lines:
                ip = re.findall(r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}", line)  # 匹配ip
                port_protocol = re.search(r"[0-9]{1,5}/\S*", line)       # 匹配协议即端口
                try:
                    portID = port_protocol.group()
                    portinfo = portID.split('/')
                    protocol = portinfo[1]
                    port = portinfo[0]
                    result = [ip[0], protocol, port]
                    # results.append(result)
                    writer.writerow(result)

                except:
                    pass
    # for result in results:
    #     print(result)

    df = pd.read_csv('masscan_data.csv')
    df = df.sort_values(by=['Address', 'Port'], ascending=True)
    df.to_csv('masscan_data.csv',index=False)
    df_sum = df.groupby('Address')['Port'].count()  # 统计扫描出的各个ip地址有多少端口
    df_sum.to_csv('masscan_sum.csv')

2. 匹配密码,手机号,邮箱:

import re


def input_pwd():
    while 1:
        pwd = input('Please Input Your Password: ')
        if len(pwd) < 8:
            print('Too short')
        elif not lower.findall(pwd):
            print('You have no lower letters!!!')
            continue
        elif not upper.findall(pwd):
            print('You have no upper letters!!!')
            continue
        elif not digit.findall(pwd):
            print('You have no digits!!!')
            continue
        elif not special.findall(pwd):
            print('You have no special characters!!!')
        else:
            print('Correct!')
            break
    return pwd


def input_phone():
    while 1:
        phone = input('Please Input Your phone number: ')
        if len(phone) != 11:
            print('Format error!')
        elif re.findall(r"1(3|4|5|7|8)\d{9}$", phone):
            phone_number = re.findall(r"1(?:3|4|5|7|8)[0-9]{9}$", phone)
            print('Correct')
            break
        else:
            print('Format error!')
    return phone_number[0]


def input_email():
    while 1:
        email = input('Please Input Your email number: ')
        if re.findall(r"[a-z0-9]+@(?:163|gmail|qq)\.com", email, re.I):
            email_number = re.findall(r"[a-z0-9]+@(?:163|gmail|qq)\.com", email, re.I)
            print('Correct')
            break
        else:
            print('Format error!')
    return email_number[0]


if __name__ == '__main__':
    lower = re.compile('[a-z]')
    upper = re.compile('[A-Z]')
    digit = re.compile('[0-9]')
    special = re.compile('[^a-zA-Z0-9]')
    password = input_pwd()
    pho = input_phone()
    ema = input_email()
    print("\nYour pwd: " + password + "\nYour phone: " + pho + "\nYour email: " + ema)

参考链接:

https://tool.oschina.net/uploads/apidocs/jquery/regexp.html(表达式全集)
https://www.runoob.com/regexp/regexp-syntax.html(正则表达式语法)
https://blog.csdn.net/stcaaa/article/details/83864210(python re库 详解)
https://blog.csdn.net/qq_40279964/article/details/82958680(贪婪匹配与非贪婪匹配)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值