首页 > 解决方案 > 在包含通配符和转义符的字符串中查找模式

问题描述

我现在在网上搜索了几个小时并尝试了几种替代方案,但找不到令人满意的解决方案。我有一个名为tmp_txt的字符串,其中包含几篇文章,它们都以

"Newspaper.com \tTopic \tXX.XX.2015\r\n\t\r\n\r\nher_goes_the_title\r\n\r\ntext_containing_\r\n\r\nsometimes"

XX.XX.2015是一个变化的日期(但总是在 2015 年)。

我想找到所有日期 ( XX.XX.2015) 和所有标题 ( here_goes_the_title) 以将它们写入数据框(对应的日期和标题在一行中,但在不同的列中)。

到目前为止,我最好的解决方案是找到所有日期,还有一些他们的环境,例如:

dates <- str_match_all(tmp_text, "\t(.*?).2015")

导致

"\tTopic \t15.09.2015"

等等

查找标题要困难得多,因为它们只能\r\n\t\r\n\r\n在每篇文章的第一个 -sequence 之后和在一篇\r\n\r\n文章中多次出现的 -sequence 之前找到。

你有什么解决办法?

提前致谢, Hanno

第一次编辑

好的,就像 r2evans 建议的那样,这里有一些例子:

Süddeutsche.de \tPolitik \t15.09.2013\r\n\t\r\n\r\nSyrien-Konflikt\r\n\r\nHollande dämpft Erwartungen an Chemiewaffen-Plan\r\n\r\n

日期应该是

15.09.2013

标题应该是

Syrien-Konflikt

如果还有一个获取第二个标题的解决方案,那就太好了:

Hollande dämpft Erwartungen an Chemiewaffen-Plan

但是,在少数情况下,标题前面带有不相关的信息:

\r\nSüddeutsche.de \tComputer \t07.09.2013\r\n\t\r\n\r\nhttp://www.sueddeutsche.de/digital/syrische-elektronische-armee-wie-syrische-hacker-im-netz-fuer-assad-kaempfen-1.1764980\r\n\r\nSyrische Elektronische Armee\r\n\r\nWie syrische Hacker im Netz für Assad kämpfen\r\n\r\n

日期应该是:

07.09.2013

标题应该是:

Syrische Elektronische Armee

第二个标题应该是

Wie syrische Hacker im Netz für Assad kämpfen

但是,有时不规则信息由两行组成,如下所示:

Süddeutsche.de \tPolitik \t03.09.2013\r\n\t\r\nKurz\r\n\r\nhttp://www.sueddeutsche.de/politik/syrisch-tuerkische-grenze-mindestens-sechs-menschen-sterben-bei-explosion-1.1761804\r\n\r\nSyrisch-türkische Grenze\r\n\r\nMindestens sechs Menschen sterben bei Explosion\r\n\r\nBei einer Explosion von Munition sind an der syrisch-türkischen Grenze...

日期:

03.09.2013

标题:

Syrisch-türkische Grenze

第二个标题:

Mindestens sechs Menschen sterben bei Explosion

r2evans 建议的第一个解决方案效果很好。但是,我知道有X篇文章,现在该函数返回 X 个日期(这是正确的),但只有X-2个标题!

我不知道,哪些标题没有正确找到。所以我想使用一个函数,它显示日期后的前 50 个字符,这将帮助我通过手动搜索找到有问题的案例,例如

Süddeutsche.de \tPolitik \t03.09.2013\r\n\t\r\nKurz\r\n\r\nhttp://www.sueddeutsche.de/politik/syrisch-tuerkische-grenze-mindestens-sechs-menschen-sterben-bei-explosion-1.1761804\r\n\r\nSyrisch-türkische Grenze\r\n\r\nMindestens sechs Menschen sterben bei Explosion\r\n\r\nBei einer Explosion von Munition sind an der syrisch-türkischen Grenze...

回报应该是:

03.09.2013\r\n\t\r\nKurz\r\n\r\nhttp://www.sueddeutsche.de/p

如果您有更好的解决方案,我会很高兴知道。

如果还有问题,请随时提问。如果您需要上传 txt.file,请告诉我。

干杯,汉诺

标签: rregexstringstringr

解决方案


基础 R 解决方案。使用强尼的txt

txt <- "Newspaper.com \tTopic \t12.02.2015\r\n\t\r\n\r\nher_goes_the_title\r\n\r\ntext_containing_\r\n\r\nsometimes"

regmatches(txt, gregexpr("\\b[0-9]{2}\\.[0-9]{2}\\.[0-9]{4}\\b", txt))
# [[1]]
# [1] "12.02.2015"
regmatches(txt, gregexpr("(?<=\r\n\t\r\n\r\n)[^\r\n]+(?=\r\n\r\n)", txt, perl = TRUE))
# [[1]]
# [1] "her_goes_the_title"

的使用gregexpr适用于多个匹配。但是,它可能会在一个字符串中找到多个日期,因此如果您开始看到该模式,请务必小心。(如果你认为你会得到它,有一些简单的方法可以修复它,例如上面的返回值lapply(x, `[[`, 1)在哪里x。)你可以作弊并使用,regexpr只要你一次只处理一个字符串,但矢量化它是从长远来看可能是一件好事。

解释:

"\\b[0-9]{2}\\.[0-9]{2}\\.[0-9]{4}\\b"
 ^^^                              ^^^  word boundaries before/after
    ^^^^^      ^^^^^      ^^^^^        character range, just digits here
         ^^^        ^^^        ^^^     number of characters in preceding match
            ^^^        ^^^             the literal dot "."

"(?<=\r\n\t\r\n\r\n)[^\r\n]+(?=\r\n\r\n)"
 ^^^^^^^^^^^^^^^^^^^                       must have this pattern before,
                                              but does not consume it
                            ^^^^^^^^^^^^   must have the pattern after, no consume
                    ^^^^^^^                any character not one of \r \n
                           ^               one or more of preceding match

的使用(?<=(?=要求perl=TRUE


推荐阅读