MyEssay 之 Python正则表达式 —— 点滴随记

  • 正则表达式pattern一定要使用raw string形式,即使用 r"..." 形式,这是因为包括 '\b'、'\1' 等字符,既是ASCII特殊字符,又是正则表达式特殊字符。如果在pattern string中没有使用 r"..." 形式,则必须使用形如 "\\b"、"\\1" 这样的转义表达,否则python解释器将会首先把 "\b" 当做ASCII特殊字符中的回退字符处理,把 "\1" 当做八进制的数来处理,这样就会出现形如 re.findall("\bthe\b", "the python is the best") 结果却为空列表的怪事。使用了raw string的形式之后,python解释器不会对字符串中的反斜线 "\" 进行转义处理,完整的 "\b" 会被发送至正则表达引擎,这样才会被当做单词边界标志来处理。 

  • 在正则表达式pattern中使用 (?P<group_name>...) 扩展模式时,如果...部分匹配成功,则可以在三种情况下使用 "groupName" 来对匹配内容进行检索和使用,被测字符串 strTest = "010 : 010-12345678"
    (1)、 pattern 字符串本身中使用 (?P=group_name)来引用匹配成功的内容,例如  result = re.match(r"(?P<areacode>\b\d+\b)[ ]:[ ](?P=areacode)-(?P<number>\d+)", strTest)
    (2)、 match object中可以使用 match.group("group_name") 来引用匹配的内容,例如 result.group("areacode") 或者 result.groupdict("areacode") 结果为 "010"
    (3)、 在正则匹配替换方法的repl参数中,可以使用 \g<group_name> 来引用pattern中匹配的内容,例如 re.sub(r"(?P<areacode>\b\d+\b)[ ]:[ ](?P=areacode)-(?P<number>\d+)", "\g<areacode> - (\g<areacode>)\g<number>", strTest) 结果为 '010 - (010)12345678',上述语句等效于 re.sub(r"(\b\d+\b)[ ]:[ ]\1-(\d+)", "\g<1> - (\g<1>)\g<2>", strTest)

  • 扩展表达式 (?:...) 的主要作用是,用于构建包含符合指定匹配规则的子字符串(即...的正则表达式匹配的内容),且匹配的子字符串我们并不关注它的具体内容的匹配内容,该匹配内容作为整体可以和*、?、+、| 等特殊字符配合使用时进行占位,最终这样的匹配内容不会保存到match object的groups中。例如需要判断一个字符串是否是合法的email地址,并且从中提取出邮箱名来:

    >>>re.search(r"\b(?P<emailName>(?:\w|[\.-])+)@(?P<suffix>(?:\w+\.)+(?P<type>\w+))", "ralph.test-2@yahoo.com.cn").groups()
    ('ralph.test-2', 'yahoo.com.cn', 'cn')

    pattern中的 (?:\w|[\.-]) 和 (?:\w+\.) 都是匹配了一个子字符串,并和+字符配合来进行复杂的占位,但是并没有在最终的匹配结果的group中保存这两个匹配结果

  • 对于在pattern中使用 (...) 或 (?P<name>...) 方式进行匹配并保存的内容,如果没有匹配成功,仍然会在结果的group中占用一个结果,只是值为None。例如:

    >>> re.search(r"(?:(?P<areacode>\b\d+\b)(?:\s*-\s*))?(?P<number>\b\d+\b)", "0755 - 12345678").groups()
    ('0755', '12345678')
    >>> re.search(r"(?:(?P<areacode>\b\d+\b)(?:\s*-\s*))?(?P<number>\b\d+\b)", "12345678").groups()
    (None, '12345678')

  • 对于上例这种 re.search(r"(?:(?P<areacode>\b\d+\b)(?:\s*-\s*))?(?P<number>\b\d+\b)", "0755 - 12345678").groups() 较复杂的pattern,最好使用 re.VERBOSE 或 re.X 标志,或者使用 (?x) 扩展表达式方式来格式化书写,并加入注释例如:

    >>> re.search(r"""(?x)
            (?:
                (?P<areacode>\b\d+\b)     # the area code group
                (?:\s*-\s*)                       # the connection token
            )? # the possible whole area code part

            (?P<number>\b\d+\b) # the phone number group
            """, "0755-12345678").groupdict()
    {'areacode': '0755', 'number': '12345678'}

  • 每一个match object都有至少一个group,其值为match object对应的子字符串,即执行matchObj.goup() 或 matchObj.group(0) 都将返回完整的匹配子字符串。当pattern中通过(...)或(?P<name>...)方式定义了其他的group时,matchObj.group(N)将会返回对应的group子字符串。
    而match object的 groups() 函数则会一个tuple,其中的每个值对应于在pattern中通过(...)或(?P<name>...)方式定义的一个group匹配的子字符串,如果pattern中没有定义group则groups()函数返回的是一个空tuple。
    ——因此 matchObj.group(N) 的值等同于 matchObj.groups()[N-1],N>0

  • re.search() 函数
        对目标字符串从左至右进行扫描,一旦发现符合pattern的子字符串(但符合pattern的子字符串的起点并不一定等于目标字符串的起点),就停止继续向右扫描,而返回match object
    re.match() 函数:
        对目标字符串从最左侧开始处进行pattern模式的匹配,如果向右移动至某个位置时匹配成功,就停止继续向右扫描,而返回match object

    re.findall() 函数:
        对目标字符串从左至右进行扫描,将会扫描直至目标字符串的结尾,并查找出整个目标字符串中所有符合pattern的子字符串,并返回这些子字符串对应的match object的groups()函数返回的tuple构成的list,如果每个match object的groups()函数返回的是空tuple,则findall()返回的则是多个匹配pattern的子字符串构成的list

    re.finditer()函数:
        的工作方式与findall()类似,只是其返回值不是一个常驻内存的list,而是一个generator,当遍历这个generator时,实时运算得到一个match object并返回,当一次遍历完成后,这个generator中的内容也就销毁不再占用内存空间了,即再次对这个generator进行遍历不会得到任何内容了

    ——因此search和match函数最多只能得到一个匹配对象,而findall和finditer函数能够得到所有的匹配对象,示例如下:

    >>>strTest = '010 : 010-12345678\nBeijing\n020 : 020-23456789\nGuangzhou\n021 : 021-34567890\nShanghai'

    >>> re.search(r"(?sm)^(?P<areacode>\d+)[ ]:[ ](?P=areacode)-(?P<number>\d+).+?(?P<name>\b\w+\b)$",strTest).groups()
    ('010', '12345678', 'Beijing')

    >>> re.findall(r"(?sm)^(?P<areacode>\d+)[ ]:[ ](?P=areacode)-(?P<number>\d+).+?(?P<name>\b\w+\b)$",strTest)
    [('010', '12345678', 'Beijing'), ('020', '23456789', 'Guangzhou'), ('021', '34567890', 'Shanghai')]

    >>> result = re.finditer(r"(?sm)^(?P<areacode>\d+)[ ]:[ ](?P=areacode)-(?P<number>\d+).+?(?P<name>\b\w+\b)$",strTest)
    >>> for item in result:
                print item.groups()

    ('010', '12345678', 'Beijing')
    ('020', '23456789', 'Guangzhou')
    ('021', '34567890', 'Shanghai')
    >>> for item in result:
                print item.groups()

    >>>

转载于:https://www.cnblogs.com/xaviercd/p/5821119.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,可以使用数学库中的函数来计算勾股定理。比如,可以使用math模块中的sqrt函数来计算平方根。以下是一个使用勾股定理计算直角三角形斜边长度的示例代码: ``` from math import * a = float(input("请输入斜边1的长度:")) b = float(input("请输入斜边2的长度:")) c = sqrt(a*a + b*b) print("斜边长为:", c) ``` 在这个例子中,用户需要输入直角三角形的两个直角边的长度,然后通过勾股定理计算出斜边的长度,并将结果输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python 基础](https://blog.csdn.net/weixin_34268310/article/details/85888761)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [python入门学习随(二)(勾股定理、球体积、利率、移位和进制转换、数字求和)](https://blog.csdn.net/small_red_cap/article/details/102773406)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值