r - 在包含通配符和转义符的字符串中查找模式
问题描述
我现在在网上搜索了几个小时并尝试了几种替代方案,但找不到令人满意的解决方案。我有一个名为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,请告诉我。
干杯,汉诺
解决方案
基础 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
。
推荐阅读
- r - 如果单元格为空,则改变数据框
- php - 使用 PHP 将 JSON 数组转换为 CSV
- javascript - 基于因子随机数生成器的 Javascript 概率选择器
- c# - 使用泛型的对象池
- javascript - 运行已编译的 Javascript 代码时,TypeScript 文件中出现“SyntaxError:无法在模块外使用导入语句”错误
- reactjs - 在 TypeScript 中将 hashmap 类型正确作为函数参数
- c# - 如何在 KeyPress 功能上添加第二个输入?
- flutter - Flutter/Retrofit:如何使用 Flutter 中的 Retrofit 在查询参数中调用具有多个排序顺序的 API?
- android - 为什么每次运行都会杀死 Android Studio Emulator 进程?
- javascript - 如何从 vuejs 中的 url(图像)获取文件类型对象