正则表达式替换匹配项,但也忽略引号内的匹配项

Regex to replace matches but also ignore when matches within quotes

正在尝试将 "and" 或 "or" 匹配并替换为“&”和“|”当它出现在引号之外时,除非它们出现在引号内。

引号可以是单引号 (') 或双引号 (")。

字符串如下:

Industry ='Education' or Industry =\"Energy\" or Industry = 'Financial or Bank' or Industry = 'Hospitality' or Industry = \"Food and Beverage\"  and Industry = 'Utilities'

预期输出:

Industry ='Education' | Industry =\"Energy\" | Industry = 'Financial or Bank' | Industry = 'Hospitality' | Industry = \"Food and Beverage\"  & Industry = 'Utilities'

我知道我们可能必须使用环顾四周,但不知道如何做。我在 R 中使用 stringr 包进行所有正则表达式操作。

如果您需要更多信息,请告诉我。

这是一种丑陋的方法,但它适用于您的特定情况:

对于或:

(?:'|")(?:.*?)(?:'|")(?:.*?)(or)(?:.*?)

对于和:

(?:'|")(?:.*?)(?:'|")(?:.*?)(and)(?:.*?)

我建议使用 https://regex101.com/ 来帮助构建和测试您的正则表达式

您的问题存在潜在问题,因为单个正则表达式可能无法很好地或根本无法处理嵌套内容。也就是说,如果我们假设您要用管道替换的 or 值总是出现在 之后 引用的字符串,那么我们可以尝试以下操作:

gsub("([\"'])\s*or", "\1 |", input)
[1] "Industry ='Education' | Industry =\"Energy\" | Industry = 'Financial or Bank' |
Industry = 'Hospitality' | Industry = \"Food and Beverage\"  and Industry = 'Utilities'"

通过检查,出现在带引号字符串内的 or 值两边都被未加引号的单词包围。显然,这可能会在看到其他数据或更多嵌套内容时崩溃。

Demo

您应该考虑一种方法来匹配双引号和单引号子字符串以忽略它们,并且只在所有其他上下文中处理 andor。最简单的方法是使用 gsubfn ,您可以在其中传递一个 PCRE 正则表达式来执行此操作:

> library(gsubfn)
> x <- "Industry ='Education' or Industry =\"Energy\" or Industry = 'Financial or Bank' or Industry = 'Hospitality' or Industry = \"Food and Beverage\"  and Industry = 'Utilities'"
> pat = "(?:\"[^\"]*\"|'[^']*')(*SKIP)(*F)|\b(and|or)\b"
> gsubfn(pat, ~ ifelse(z=="or","|", "&"), x, backref=0, perl=TRUE)
[1] "Industry ='Education' | Industry =\"Energy\" | Industry = 'Financial or Bank' | Industry = 'Hospitality' | Industry = \"Food and Beverage\"  & Industry = 'Utilities'"

(?:\"[^\"]*\"|'[^']*')(*SKIP)(*F)|\b(and|or)\b 模式将匹配:

  • (?: - 交替组:
    • \"[^\"]*\" - 内部没有双引号的双引号子字符串
    • | - 或
    • '[^']*' - 单引号子字符串
  • ) - 小组结束
  • (*SKIP)(*F) - 放弃匹配,继续寻找下一个匹配
  • | - 或
  • \b(and|or)\b - 第 1 组:andor 作为一个完整的词。

参见regex demo

根据 "'"..."'...' 中转义的方式,您需要调整正则表达式的 (?:\"[^\"]*\"|'[^']*') 部分.

~ ifelse(z=="or","|", "&") 部分是一个回调函数,它接收唯一的参数(在该函数中名为 z),其内容是您从正则表达式中获得的匹配值(即 orand)。如果匹配值等于 or,则匹配替换为 |,否则替换为 &.