【问题标题】:Suggestions on Word Parsing单词解析的建议
【发布时间】:2015-07-01 06:08:37
【问题描述】:

我有一组具有任意名称的文件夹和文件。我的最终目标是解析文件夹和文件,并创建一组分类良好且命名的文件夹。这些标题有时有空格作为分隔符,有时有句点(我没有找到除分隔符之外的任何示例)。我想显示这些文件名,不带分隔符,只显示真实的单词(具体的文件标题和日期,如果日期相关)。我暂时不用担心日期,我有一个查找表可以根据拼写正确的标题找出日期。

标题示例

  1. a.bad.title.asdf.1975(其中 asdf 是从作者或网站上抓取文件)。

标题应为: A Bad Title (1975)

  1. another bad title asdf.com 1975

应改为: Another Bad Title (1975)

  1. a really.bad title[1975]

应改为:A Really Bad Title (1975)

我的尝试:

可能的解决方案:使用分隔符解析单词以提取每个单独的单词并使用大型字典进行单词搜索我必须弄清楚数组的给定元素是否是单词.

问题 1: A.bad.title.1975 变为 ('a', 'bad', 'title', '1975'),我可以毫无问题地使用它。然而,一个非常糟糕的标题[1975] 变成了('a', 'really', 'bad', 'title[1975]') 并且无法处理。

问题 2: 有些标题是数字或数字的一部分,例如 '7120122001: A Space Odyssey,所以我不能只解析真正的单词是什么。

编辑(问题 2 示例):

文件名 1:'72.2014.asdf.txt

文件名 2:2012 [2009].txt

文件名 3:2001: a.space.odyssey[1968].txt

编辑结束

换句话说,我的问题是我希望能够删除给定的日期或随机数,但如果日期与标题有关(因为某些标题是日期或年份)和一些标题中的单词附加在标题中的年份(不带空格),无法解析。

我的最后一个想法可能是根据每个可能的标题有多少共同词来给它们打分,但这仍然没有解决“年份作为标题”的问题。

如果有人有任何建议可以帮助我思考这个问题,请告诉我!

【问题讨论】:

  • @Pradheep 代码没有任何问题,这是我遇到问题的代码背后的逻辑。

标签: python regex parsing date


【解决方案1】:

以下代码将实现大部分预期的结果。它可以很容易地改写为使用正则表达式,但我觉得在这种格式下,如果您在文件夹结构中发现其他没有按需要转换的情况,进一步调整会更容易。

ltest = ["a.bad.title.asdf.1975", "another bad title asdf.com 1975", "a really.bad title[1975]"]

lsub = [(".", " "), ("_", " "), ("[", " "), ("(", " "), ("]", " "), (")", " ")]

for test in ltest:
    # Remove all unwanted characters

    for before, after in lsub:
        test = test.replace(before, after)

    # Split into a list of non-empty words

    ltest = test.split(" ")
    ltest = [test for test in ltest if len(test)]

    # Join them back together with a single space and wrap the last word in parenthesis

    test = " ".join(ltest[:-1]) + " (%s)" % ltest[-1]
    output = test.title().strip()

    print "'%s'" % output

这给出了以下输出:

'A Bad Title Asdf (1975)'
'Another Bad Title Asdf Com (1975)'
'A Really Bad Title (1975)'

我认为你需要举一些关于你的“问题 2”的例子

更新

lsub 可以扩展到处理特定的网站,但要知道一个词是否是作者将是一个挑战。

例如

lsub = [("asdf.com", " "), (".", " "), ("_", " "), ("[", " "), ("(", " "), ("]", " "), (")", " ")]

这将解决第二个测试:

'Another Bad Title (1975)'

【讨论】:

  • 他想摆脱“asdf”和“asdf.com”,我从问题中假设。不过,在格式方面获得某种标准是件好事。
  • 同意。我看不到删除这些的通用解决方案,但是如果它们是从少数站点中删除的,那么很容易将它们显式添加到 lsub 列表中。
  • 谢谢大家,我没想到用括号和方括号代替空格!这看起来很简单,但实际上很棒!此外,不仅仅是asdf。有时,只是大量与标题无关的随机文本和内容,但我认为这将有助于清除它!
  • 我还添加了问题 2 的 3 个示例,马丁!谢谢!
【解决方案2】:

又快又脏:

import re

for title in [
        "a.bad.title.asdf.1975",
        "another bad title asdf.com 1975",
        "a really.bad title[1975]"]:
   print(" ".join(map(str.title, re.findall(r"\w+", title))))

输出

A Bad Title Asdf 1975
Another Bad Title Asdf Com 1975
A Really Bad Title 1975

在这种形式中,应该很容易与已知标题进行比较。

【讨论】:

    【解决方案3】:

    您可以进行一些预处理以尝试去除多余的信息。如果不需要的部分数量非常有限,请查看 Martin 的答案的更新,并为它们命名。

    如果它们太多,请找出标题中不需要的部分常见的格式类型。您需要查看它们的格式并尝试通过首先识别它们来避免这些部分。

    例如,(?:(?<=\s|^)([^.]*?)(?:\s|$)) 将仅捕获除以空格且不包含点的单词,避免使用站点名称。请参阅:https://regex101.com/r/rK9zJ2/3another bad title asdf.com 1975 将变成another bad title 1975 并且易于处理。现在,这不是您的问题的解决方案,因为它不处理 another.bad.title.1934,但您明白了 - 知道您想要避免哪些类型的信息。

    您可能会发现需要删除站点名称。 (?<=\s|^|\.)(?:\w*?\.(?:com|de|org|se)|(\w*?))(?=\s|$|\.) 是我制作的一个正则表达式,它也处理really.bad.titles,但不捕获站点。 (.com、.de、.org、.se)指定。见DEMO。正则表达式并不是最简单的方法(尽管可能是最短的代码长度)。

    a.really.bad.title.by.asfd.1995 可能是另一回事,将by someoneby someone.com 添加到您不想捕获的内容中:(?<=\s|^|\.)(?:\w*?\.(?:com|de|org|se)|by(?:\s|.)\w*?(?:\.(?:com|de|org|se))?|(\w*?))(?=\s|$|\.),如https://regex101.com/r/rK9zJ2/5 所示。现在,当您使用正则表达式执行此类操作时,它们往往会变得冗长且难以阅读。虽然有诀窍。总而言之,决定你不想捕获的内容并弄清楚如何使用正则表达式或其他方式编写格式。没有办法指定你想要避免什么。

    【讨论】:

    • 这非常有效!我仍然无法弄清楚如何在正则表达式中添加具有 www.something.com 的 URL。不会只是(?:www.) 吗?还是我错过了什么?
    【解决方案4】:

    我发现了一个非常好的正则表达式,它可以在遵循这些规则的同时发挥作用:

    1. 没有标点符号,除了撇号和 $、# 和 !

    2. 下划线应该是空格。

    这里是:

    new_title = re.sub(ur"[^\$#! | ^\w\d'\s]+",' ',title).replace('_', ' ')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 2021-12-05
      • 1970-01-01
      相关资源
      最近更新 更多