正则表达式替换匹配但在引号内匹配时也会忽略

时间:2017-11-28 11:29:24

标签: r regex regex-lookarounds stringr

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

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

字符串如下:

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包进行所有正则表达式操作。

如果您需要更多信息,请与我们联系。

3 个答案:

答案 0 :(得分:3)

您应该考虑使用匹配双引号和单引号子字符串的方法来省略它们,并且只在所有其他上下文中处理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

根据文字"'如何在"..."'...'内转义,您需要调整正则表达式的(?:\"[^\"]*\"|'[^']*')部分。< / p>

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

答案 1 :(得分:0)

这是一种难看的方式,但它适用于您的特定情况:

对于Or:

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

For And:

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

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

答案 2 :(得分:0)

您的问题存在潜在问题,因为嵌套内容可能无法通过单个正则表达式处理得很好或根本无法处理。话虽这么说,如果我们假设你想用管道替换的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