首页 > 解决方案 > R中的正则表达式来检测三个单词的组合和这些单词的变体

问题描述

我在正则表达式方面不是很有经验,所以我正在伸出援手。如果这是一个重复的问题,请指出我的其他回答。

我的字符串包含三个分组的单词。这三个词可以在每个组中以任何顺序出现。这些词代表零件编号及其修订,可能会出现单词“rev”(简称:修订)的变体。修订版也可能不存在。三个字中的两个同属一个:如果有两个 7 位数字,则必须有两个修订!

业务背景:我们有一个工程变更数据库,有些变更只包含正在变更的零件的零件编号。相关的修订在描述字段中。通常,描述包含部件号和修订以及其他文本。我需要从描述中找出零件的修订版本。

匹配 我需要返回部件号及其相关修订。

简单和最常见的情况

这三个单词以任意顺序出现一次。单词之间可以有空格,也可以有逗号、冒号、其他文本或其组合。“REV”和变体是可选的。

更复杂的案例

这三个单词以混合顺序多次出现。现实世界组合的例子:

但是破坏组的组合是不可能的。例如:

是不可能的(如果他们愿意,我想忽略它们)。换句话说:如果有一个 7 位的字符串,它后面必须跟一个修订版。如果有两个相邻的 7 位字符串,则前后必须有一个修订。等等

我希望这足够清楚。乐于使用base正则表达式或例如stringr函数。您的帮助将不胜感激。

更新 一些更明确的说明,使用括号表示组,并使用字母 A(7 位字符串)、B(字符串“REV”和变体)和 C (A00) 表示单词。现实的组合,注意 A 和 C 必须存在于一个组中:

不可能的组合:

A 的出现必须在同一组中看到 C。一个 A 不能与多个 B 或 C 相关联。我想如果我们完全忽略 B,这个问题可以简化。

标签: rregex

解决方案


您可以尝试查找“字母 + 2 位”+“7 位”或交换相同内容的正则表达式。对于提供的示例,此方法有效:

s = "1234567 Rev A00 7654321 B00 Rev C00 1357913 1337335 Rev A00, 1337336
1234567 Rev A00 some random text 7654321 B00 Rev C00 1357913 1337335 Rev A00
1337336 Rev A00, 1337338 Rev. A00, and 1337339 REV A00
1281660 A01, 1281661 B00,1281839 A01
A01 1281660 1281661 B00 A01 1281839
Rev A01 1281660, REV. B00 1281661, 1281839 A01"

library(stringr)

z = str_match_all(s, "([A-Z]\\d{2}.+?\\d{7}|\\d{7}.+?[A-Z]\\d{2})")

这将返回:

> z
[[1]]
      [,1]               [,2]              
 [1,] "1234567 Rev A00"  "1234567 Rev A00" 
 [2,] "7654321 B00"      "7654321 B00"     
 [3,] "C00 1357913"      "C00 1357913"     
 [4,] "1337335 Rev A00"  "1337335 Rev A00" 
 [5,] "1234567 Rev A00"  "1234567 Rev A00" 
 [6,] "7654321 B00"      "7654321 B00"     
 [7,] "C00 1357913"      "C00 1357913"     
 [8,] "1337335 Rev A00"  "1337335 Rev A00" 
 [9,] "1337336 Rev A00"  "1337336 Rev A00" 
[10,] "1337338 Rev. A00" "1337338 Rev. A00"
[11,] "1337339 REV A00"  "1337339 REV A00" 
[12,] "1281660 A01"      "1281660 A01"     
[13,] "1281661 B00"      "1281661 B00"     
[14,] "1281839 A01"      "1281839 A01"     
[15,] "A01 1281660"      "A01 1281660"     
[16,] "1281661 B00"      "1281661 B00"     
[17,] "A01 1281839"      "A01 1281839"     
[18,] "A01 1281660"      "A01 1281660"     
[19,] "B00 1281661"      "B00 1281661"     
[20,] "1281839 A01"      "1281839 A01"     

执行z[[1]][,1]以返回第一列。

您可以在此 Regex101中尝试更多案例(它在 PHP 中,但唯一的区别是在 R 中您需要双反斜杠\\而不是一个\)。


推荐阅读