【问题标题】:Negative lookbehind in R with multi-word separationR中带有多词分离的负向回溯
【发布时间】:2017-06-30 21:31:36
【问题描述】:

我正在使用 R 进行一些字符串处理,并且想识别具有某个词根且前面没有某个词根的另一个词的字符串。

这是一个简单的玩具示例。假设我想识别在字符串中的任何位置都没有以“dog/s”开头的单词“cat/s”的字符串。

 tests = c(
   "dog cat",
   "dogs and cats",
   "dog and cat", 
   "dog and fluffy cats",
   "cats and dogs", 
   "cat and dog",  
   "fluffy cats and fluffy dogs")  

使用这个模式,我可以拉出 确实在 cat 之前有 dog 的字符串:

 pattern = "(dog(s|).*)(cat(s|))"
 grep(pattern, tests, perl = TRUE, value = TRUE)

[1] "dog cat"  "dogs and cats"   "dog and cat"   "dog and fluffy cats"

我的负面观察有问题:

 neg_pattern = "(?<!dog(s|).*)(cat(s|))"
 grep(neg_pattern, tests, perl = TRUE, value = TRUE)

grep 中的错误(neg_pattern,tests,perl = TRUE,value = TRUE): 无效的正则表达式

另外:警告信息: 在 grep(neg_pattern, tests, perl = TRUE, value = TRUE) : PCRE 模式编译错误 'lookbehind断言不是固定长度' 在')(猫(s|))'

我知道 .* 不是固定长度的,那么如何拒绝在“cat”之前有“dog”并由任意数量的其他单词分隔的字符串?

【问题讨论】:

  • 是的,您的“负前瞻有问题”,因为它不是前瞻,而是不能具有未知长度模式的后瞻。看起来您可以通过这种方式使用 lookahead - "^(?!.*dog.*cat).*cat"
  • 看起来你不能在 R 中的单个正则表达式中做你想做的事。这里也有同样的问题有一个很好的答案:stackoverflow.com/questions/3796436/…
  • @WiktorStribiżew 我试图理解我的问题的词根部分。例如,猫 vs 猫 vs 毛毛虫……我可以使用 cat(s|erpillar|) 等吗?
  • 那么永远不要过于简单化。发布真实场景问题的详细信息。清醒的人一定会帮助你。

标签: r regex lookbehind


【解决方案1】:

我希望这可以帮助:

tests = c(
  "dog cat",
  "dogs and cats",
  "dog and cat", 
  "dog and fluffy cats",
  "cats and dogs", 
  "cat and dog",  
  "fluffy cats and fluffy dogs"
)

# remove strings that have cats after dogs
tests = tests[-grep(pattern = "dog(?:s|).*cat(?:s|)", x = tests)]

# select only strings that contain cats
tests = tests[grep(pattern = "cat(?:s|)", x = tests)]

tests

[1] "cats and dogs"               "cat and dog"                
[3] "fluffy cats and fluffy dogs"

我不确定你是否想用一种表达方式做到这一点,但是 正则表达式在迭代应用时仍然非常有用。

【讨论】:

    猜你喜欢
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多