【问题标题】:Regex not specific enough正则表达式不够具体
【发布时间】:2021-07-22 23:15:28
【问题描述】:

所以我为我的 Kindle 电子阅读器编写了一个程序,它可以搜索我的亮点并删除重复的文本(通常是关于书名、作者、页码等的信息)。我认为它是功能性的,但有时在输出的某些行上会随机出现句点 (.)。一开始我以为这个程序有问题,但后来我意识到我用来匹配书名和作者的正则表达式也匹配任何以括号结尾的句子。

这是我用来检测书名和作者的正则表达式代码

titleRegex = re.compile('(.+)\((.+)\)')

示例

  • 所需的书名和作者匹配:书名(作者姓名)
  • 还可以匹配的内容: *我喜欢苹果,因为它们是绿色的(它们有时也是红色的)。 *

在这种情况下,它会删除所有内容,只留下句末的句号。这显然不理想,因为它删除了我突出显示的文本

Here is the unformatted text file that goes into my program

该程序的工作原理是查找我编写的正则表达式的所有匹配项,循环遍历这些匹配项,并用空字符串一一替换它们。

是否有任何方法可以使我的标题正则表达式更加具体,以便它只选择作者标题而不是以括号结尾的完整句子?如果没有,我必须采取哪些步骤来重组这个程序?

我已将我的代码附在这篇文章的底部。我将非常感谢任何帮助,因为我是一个完全的编码新手。谢谢:)

import re
titleRegex = re.compile('(.+)\((.+)\)')
titleRegex2 = re.compile(r'\ufeff (.+)\((.+)\)')
infoRegex = re.compile(r'(.) ([a-zA-Z]+) (Highlight|Bookmark|Note) ([a-zA-Z]+) ([a-zA-Z]+) ([0-9]+) (\|)')
locationRegex = re.compile(r' Location (\d+)(-\d+)? (\|)')
dateRegex = re.compile(r'([a-zA-Z]+) ([a-zA-Z]+) ([a-zA-Z]+), ([a-zA-Z]+) ([0-9]+), ([0-9]+)')
timeRegex = re.compile(r'([0-9]+):([0-9]+):([0-9]+) (AM|PM)')
newlineRegex = re.compile(r'\n')
sepRegex = re.compile('==========')

regexList = [titleRegex, titleRegex2, infoRegex, locationRegex, dateRegex, timeRegex, sepRegex, newlineRegex]

string = open("/Users/devinnagami/myclippings.txt").read()

for x in range(len(regexList)):
    newString = re.sub(regexList[x], ' ', string)
    string = newString

finalText = newString.split('             ')

with open('booknotes.txt', 'w') as f:
    for item in finalText:
        f.write('%s\n' % item)

【问题讨论】:

  • 我喜欢苹果,因为它们是绿色的与有效的书名有什么区别? (我不得不说“什么都没有”。)它们有时也是红色的与有效的作者姓名有什么区别?如果您不能为其中至少一个提出万无一失的规则,那么您的问题就无法解决。
  • 您可以从 "^=====" 到第二个换行符进行多行匹配。

标签: python regex kindle


【解决方案1】:

没有足够的信息来判断“书名(书作者)”是否不同于“我喜欢书(好书)”等没有上下文的内容。谢天谢地,你展示的文字有很多上下文。您可以将它们组合成一个表达式来对上下文进行编码,而不是创建几个不同的正则表达式。

例如:

quoteInfoRegex = re.compile(
    r"^=+\n(?P<title>.*?) \((?P<author>.*?)\)\n" + 
    r"- Your Highlight on page (?P<page>[\d]+) \| Location (?P<location>[\d-]+) \| Added on (?P<added>.*?)\n" + 
    r"\n" + 
    r"(?P<quote>.*?)\n", flags=re.MULTILINE)

for m in quoteInfoRegex.finditer(data):
    print(m.groupdict())

这将提取文本的每一行,并对其进行解析,知道书名是等号之后的第一行,而引号本身在其下方。

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 2012-03-31
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    相关资源
    最近更新 更多