首页 > 编程问答 >正则表达式:有没有一种方法可以提取单引号之间的所有子字符串,而不提取撇号之间的子字符串?

正则表达式:有没有一种方法可以提取单引号之间的所有子字符串,而不提取撇号之间的子字符串?

时间:2024-08-01 14:59:43浏览次数:11  
标签:python regex text

基本上,我有一个包含英语语句的数据集。有些语句包含前导/尾随标点符号,所以我想清理和标准化它们。标准化的标准是删除所有前导/尾随标点符号,语句的第一个字符大写,并且语句以句点结尾。我有一个函数可以执行此操作并将其应用于数据集中的每一行。

如果有帮助的话,这里是一个代码片段:

def normalize_statement(statement):
    # remove leading/trailing punctuation and excess whitespace
    cleaned = statement.strip(whitespace + punctuation)
    cleaned = re.sub(r'\s+', ' ', cleaned)

    # capitalize first letter 
    cleaned = cleaned[0].upper() + cleaned[1:]

    # ensure the statement ends with a period
    if cleaned and not cleaned.endswith('.'):
            cleaned += '.'
    return cleaned

此函数适用于基本语句,但并不总是适用于 double 或 之间包裹的子字符串单引号,特别是当带引号的子字符串出现在语句的开头和/或结尾时,因为在删除前导标点符号后,其中一个引号会被删除(即 '"this" is a statement' 将成为 'This" is a statement' )。目的应该是在清理后保留任何子字符串周围的引号。

我考虑过使用正则表达式来捕获单引号或双引号之间的所有子字符串,用捕获的组替换所有带引号的子字符串以删除引号,标准化语句,然后将引用的子字符串添加回其原始位置。这是更新后的函数:

def normalize_statement(statement):
    # extract any and all substrings enclosed in quotation marks
    quoted_pattern = re.compile(r'["\'](.*?)["\']')
    quoted_substrings = quoted_pattern.findall(statement)

    # replace the quoted substrings with the captured groups
    cleaned = re.sub(quoted_pattern, lambda m: m.group(1), statement)

    # remove leading/trailing punctuation and excess whitespace
    cleaned = cleaned.strip(whitespace + punctuation)
    cleaned = re.sub(r'\s+', ' ', cleaned)

    # capitalize first letter for languages that use capitalization
    cleaned = cleaned[0].upper() + cleaned[1:]

    # ensure the statement ends with a period
    if cleaned and not cleaned.endswith('.'):
            cleaned += '.'

    # replace quoted substrings (if any) back into their original positions after cleaning
    for quoted_substring in quoted_substrings:
        cleaned = re.sub(re.escape(quoted_substring.strip(whitespace + punctuation)), f'\"{quoted_substring}\"', cleaned, flags=re.IGNORECASE)

    return cleaned

虽然正则表达式模式 ["\'](.*?)["\'] 有时有效(即“期望”员工拥抱“节俭”。),但对于“没有像家这样的地方,强调独特的舒适度”这样的陈述,它会失败自己周围的环境。因为在这种情况下捕获的组将是撇号之间的子字符串:“没有像家一样的地方,强调一个人的独特舒适感”。

我只想捕获引号之间的文本 - 但如何区分撇号和我的正则表达式模式中的单引号?我对正则表达式不太熟悉,所以如果有人有不同的方法,将不胜感激!


当然可以!可以修改正则表达式以仅匹配单引号,而不是撇号。以下是一种方法:

import re

def normalize_statement(statement):
    # 使用以下正则表达式匹配单引号之间的子字符串,而忽略撇号
    quoted_pattern = re.compile(r"(?<!\w)'(.*?)'(?!\w)")
    quoted_substrings = quoted_pattern.findall(statement)

    # 将引用的子字符串替换为占位符,以保留它们在清理过程中的位置
    for i, quoted_substring in enumerate(quoted_substrings):
        statement = statement.replace(quoted_substring, f"__placeholder_{i}__")

    # 删除前导/尾随标点符号和多余的空白
    cleaned = statement.strip(whitespace + punctuation)
    cleaned = re.sub(r'\s+', ' ', cleaned)

    # 将第一个字母大写
    cleaned = cleaned[0].upper() + cleaned[1:]

    # 确保语句以句点结尾
    if cleaned and not cleaned.endswith('.'):
        cleaned += '.'

    # 将引用的子字符串放回其原始位置
    for i, quoted_substring in enumerate(quoted_substrings):
        cleaned = cleaned.replace(f"__placeholder_{i}__", f"'{quoted_substring}'")

    return cleaned

正则表达式的解释:

  • (?<!\w) :这是一个负向回溯断言,它确保单引号 ( ' ) 前面没有字母数字字符 ( \w )。这有助于排除撇号,因为撇号通常出现在单词中。
  • ' :这与一个单引号匹配。
  • (.*?) :这与任何字符匹配零次或多次,非贪婪,并将匹配项捕获到组 1 中。
  • ' :这与另一个单引号匹配。
  • (?!\w) :这是一个正向断言,它确保单引号 ( ' ) 后面没有字母数字字符 ( \w )。这也有助于排除撇号。

通过使用此改进的正则表达式,的代码将仅提取由单引号包围的子字符串,而忽略用作撇号的单引号。让我们知道这对是否有效!

标签:python,regex,text
From: 78819189

相关文章

  • C++11 中的 python 海象运算符 (:=) 等效吗?
    最近我在Python中经常使用:=运算符,这样:ifmy_object:=SomeClass.function_that_returns_object():#dosomethingwiththisobjectifitexistsprint(my_object.some_attribute)问题有没有办法在c++11中做到这一点而不使用stdlib?例如......
  • Python 自动创建阿里云 OSS 桶并配置静态网站托管
    在本文中,我们将介绍如何使用Python和阿里云OSSSDK自动创建OSS桶(如果不存在),并为新创建的桶配置静态网站托管。这对于自动化部署和管理静态网站非常有用。前提条件安装阿里云OSSSDK:pipinstalloss2准备好阿里云OSS的访问密钥(AccessKeyID和AccessKeySecret......
  • visual studio 2019下Python的开发环境搭建
    Python的开发环境有各种各样的,在Windows下可以通过各种IDE(IIntegratedDevelopmentEnvironment)来进行开发,比如Pycharm,Spyder,Thonny,Eclipse+PyDev等等一些琳琅满目的编辑器,当然还有我的选择VisualStudio。之所以会选择VS,是因为VS本身就是一个功能非常强大的集成开发环境,其优......
  • 用Python编写你的网络监控系统详解
    概要在现代网络管理中,实时监控网络流量和状态是保证网络正常运行的关键。使用Python编写网络监控工具可以帮助管理员及时发现和解决网络问题。本文将详细介绍如何使用Python编写网络监控工具,包括基本概念、常用库及其应用场景,并提供相应的示例代码。网络监控的基本概念网......
  • Python WSGI服务器库之gunicorn使用详解
    概要在部署PythonWeb应用程序时,选择合适的WSGI服务器是关键的一步。Gunicorn(GreenUnicorn)是一个高性能、易于使用的PythonWSGIHTTP服务器,适用于各种应用部署场景。Gunicorn设计简洁,支持多种工作模式,能够有效地管理和处理大量并发请求。本文将详细介绍Gunicorn......
  • 基于python电影播放平台的设计与实现【源码+文档+PPT】
    ......
  • Python中FastAPI项目使用 Annotated的参数设计
    在FastAPI中,你可以使用PEP593中的Annotated类型来添加元数据到类型提示中。这个功能非常有用,因为它允许你在类型提示中添加更多的上下文信息,例如描述、默认值或其他自定义元数据。FastAPI支持Annotated类型,这使得你可以为路径操作函数的参数提供额外的元数据,例如依赖项、查询参......
  • 三种语言实现计算二进制中1的个数(C++/Python/Java)
    题目给定一个长度为n的数列,请你求出数列中每个数的二进制表示中1的个数。输入格式第一行包含整数n。第二行包含n个整数,表示整个数列。输出格式共一行,包含n个整数,其中的第i个数表示数列中的第i个数的二进制表示中1的个数。数据范围1≤n≤100000,0≤数列中......
  • 三种语言实现双指针判断子序列(C++/Python/Java)
    题目给定一个长度为n的整数序列a1,a2,…,an以及一个长度为m的整数序列b1,b2,…,bm。请你判断a序列是否为b序列的子序列。子序列指序列的一部分项按原有次序排列而得的序列,例如序列{a1,a3,a5}是序列{a1,a2,a3,a4,a5}的一个子序列。输入格式第一行包含两个整数......
  • 三种语言实现双指针解决数组元素的目标和(C++/Python/Java)
    题目给定两个升序排序的有序数组A和B,以及一个目标值x。数组下标从0开始。请你求出满足A[i]+B[j]=x的数对(i,j)。数据保证有唯一解。输入格式第一行包含三个整数n,m,x,分别表示A的长度,B的长度以及目标值x。第二行包含n个整数,表示数组A。第三行包含m个整数......