关于Word解析的建议

时间:2015-07-01 06:08:38

标签: python regex parsing date

我有一组具有任意名称的文件夹和文件。我的最终目标是解析文件夹和文件,并创建一个精心排序和命名的文件夹集。这些标题有时会以空格作为分隔符,有时会有句点(我没有找到除分隔符以外的任何其他示例)。我想显示这些没有分隔符的文件名,只显示真实的单词(具体是文件的标题和日期相关的日期)。我现在不担心日期,我有一个查找表,根据拼写正确的标题来计算日期。

标题示例

  1. a.bad.title.asdf.1975(其中asdf是文件被删除的作者或网站)。
  2. 标题应为: A Bad Title (1975)

    1. another bad title asdf.com 1975
    2. 应阅读: Another Bad Title (1975)

      1. a really.bad title[1975]
      2. 应阅读: 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

        END OF EDIT

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

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

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

4 个答案:

答案 0 :(得分:2)

以下代码将实现大部分所需结果。它可以很容易地重写为使用正则表达式,但我觉得在你的文件夹结构中发现其他不需要转换的情况时,如果你发现其他情况更容易进一步调整。

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可以扩展到处理特定网站,但知道单词是否是作者将是一个挑战。

e.g。

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

这将解决第二次测试:

'Another Bad Title (1975)'

答案 1 :(得分:1)

你可以做一些预处理来试图摆脱额外的信息。如果不需要的部分数量非常有限,请查看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所示}。现在,当您使用正则表达式执行此类操作时,它们往往会变得冗长且难以阅读。虽然这个伎俩。总而言之,决定你想要捕获什么,并找出如何使用正则表达式或其他方式编写格式。没有办法指定你想要避免的东西。

答案 2 :(得分:1)

Quick n'Dirty:

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 :(得分:0)

我发现了一个非常好的正则表达式,可以遵循这些规则:

  1. 除了撇号和$,#和!

  2. 之外没有标点符号
  3. 下划线应为空格。

  4. 这是:

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