在 r 中提取带有正则表达式的子字符串,输出带有矩阵的列表

Extracting substring with regex in r, output list with matrix

提问人:H.Stevens 提问时间:10/24/2023 最后编辑:Wiktor StribiżewH.Stevens 更新时间:10/24/2023 访问量:55

问:

我想从 r 中的字符串中提取子字符串。我用 regex101 测试了它,它确实提取了我想要的子字符串,但它也匹配了我字符串中的所有其他字符,并为我提供了一个带有矩阵的列表,它试图匹配字符串中的每个字符,但由于它只匹配几个,我得到很多空字符串。我只想要匹配结果,不想要列表或矩阵或其他。

我有一个参考书目,想提取对一卷、一期或一个数字(包括以下数字,罗马和阿拉伯)的每一次引用。因此,它计算了 Volume、Issue 和 Number 1 以及 I 或 II。有时,我的字符串中也有多个(第 3 卷,第 2 期)。 谁能告诉我为什么它会检查每个字符?

这是我到目前为止的代码:

string <- 'ABC  (2013c), Something Something Text (Volume II): Some more blabla, the usual, end of string'

pattern <- "[V|v]ol(?:ume)?\\s*(\\d+|(V?I{0,3}X?L?C{0,3}D?M?))|(?:\\s+(Issue|No|Nr|nr|no|Number)\\s*(\\d+|V?I{0,3}X?L?C{0,3}D?M?))?"
  matches <- str_match_all(string , pattern)
r 正则表达式 字符串

评论

1赞 Wiktor Stribiżew 10/24/2023
首先,必须在字符串文字中。二、为什么要用???为什么要将字符串视为向量?即使您只是将字符串用作模式,它也会匹配空字符串,因此它将匹配不匹配字符之前的任何位置。第二个模式(之后)是可选的,您必须删除可选的外部组。\s*\\s*paste(pattern, collapse = "|")|
0赞 Wiktor Stribiżew 10/24/2023
我怀疑你想要类似的东西 regex101.com/r/EkOOtw/1
0赞 Wiktor Stribiżew 10/24/2023
regex101.com/r/EkOOtw/2 / ideone.com/WTZTgX
0赞 H.Stevens 10/24/2023
太好了,这解决了它!谢谢!所以单词边界是使它不检查每个字符的东西吗?
0赞 Wiktor Stribiżew 10/24/2023
不。与空字符串不匹配的模式。

答:

1赞 Wiktor Stribiżew 10/24/2023 #1

主要问题是,之后的模式部分被一个可选的非捕获组包装,即使所有其他拼写错误都已修复,该问题仍然需要解决。|

OR 运算符两端的数字匹配部分相同,因此您可以将两个备选方案合并为一个,只需使用

string <- 'ABC  (2013c), Something Something Text (Volume II): Some more blabla, the usual, end of string'
 
rx <- paste0("\\b(?:[Vv]ol(?:ume)?|Issue|No|Nr|nr|no|Number)\\s*(?:\\d+|V?I{0,3}X?L?C{0,3}D?M?)")
library(stringr)
str_extract_all(string, rx)
## => [[1]]
##    [1] "Volume II"

在线观看 R 演示

该模式将如下所示

\b(?:[Vv]ol(?:ume)?|Issue|No|Nr|nr|no|Number)\s*(?:\d+|V?I{0,3}X?L?C{0,3}D?M?)

请参阅正则表达式演示细节

  • \b- 单词边界
  • (?:[Vv]ol(?:ume)?|Issue|No|Nr|nr|no|Number) - volVolvolumeVolumeIssueNoNrnrnoNumber
  • \s*- 零个或多个空格
  • (?:\d+|V?I{0,3}X?L?C{0,3}D?M?)- 一个或多个数字或一个可选,然后是 0 到 3 个 s,然后是可选 、 可选 、 C 零到三个出现,然后是可选和可选。VIXLDM