Regex Group Backref 不匹配值

Regex Group Backref non-matching value

我正在执行一项常见任务,即尝试从格式不一致的字符串条目中获取日期,这些条目中的数字看起来也很像日期。大多数日期中存在的一个重要的格式一致性是数字之间的分隔符是一致的。

library(stringr)
library(dplyr)

dat1 = c("01-25-2019", "15 01 2018", "01.16.2018", "01.24 2018", "01.22 19 PSI", "10.19 PSI", "01.01.01")

dat1 %>% str_extract("[0-9]{1,4}([- /\.])[0-9]{1,4}(\1[0-9]{1,4}|)")
# [1] "01-25-2019" "15 01 2018" "01.16.2018" "01.24"      "01.22"      "10.19"      "01.01.01"  

反向引用似乎可以有效地与分隔符保持一致。我还想做的是对不匹配项进行反向引用,这样如果一年在一个位置匹配 201[5-9]" it cannot be matched in another location. Likewise with month or day. At times I would also need to allow the year to be implied by context. That is what the last group(...|)` 正在做。

以下是我尝试使用 ^ 作为匹配符。

dat1 %>% str_extract("([0-3][0-9]|[0-3][0-9]|(201[5-9]|1[5-9]))([ /\.])(^\1)(\3(^\1)|)")

# [1] NA         NA         NA         NA         NA         NA         NA

我不确定在这种情况下是否使用反向引用,但如果格式不总是一致,使用前瞻可能有意义。使用您的数据 + "01.22.19 PSI""01.24 2018 19 PSI" 作为额外的测试用例:

dat1 = c("01-25-2019", "15 01 2018", "01.16.2018", "01.24 2018", "01.24 2018 19 PSI", "01.22 19 PSI", "10.19 PSI", "01.01.01", "01.22.19 PSI")

重要的是最后一组,它查找由 space、连字符或句点分隔的 2-4 位数字,如果后跟行尾或 space 加另一个数字。否则最后的分隔符必须是连字符或句点:

str_extract(dat1, "\d{2}[-\. ]\d{2}([-\. ]\d{2,4}(?= \d|$)|[-\.]\d{2,4})?")

#### OUTPUT ####
[1] "01-25-2019" "15 01 2018" "01.16.2018" "01.24 2018" "01.24 2018" "01.22"      "10.19"      "01.01.01"   "01.22.19" 

明显的好处是它也可以处理不一致的格式,例如 "01.24 2018""01.24 2018 19 PSI"。它可能仍需要一些微调,但我认为基于此原则构建应该相当简单。

我经常使用的另一种更简单的方法是先消除明显的 non-matches。例如,首先删除一些数字前面的 PSI,然后再查找日期可能更容易。