正则表达式替换匹配项,但也忽略引号内的匹配项
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
值两边都被未加引号的单词包围。显然,这可能会在看到其他数据或更多嵌套内容时崩溃。
您应该考虑一种方法来匹配双引号和单引号子字符串以忽略它们,并且只在所有其他上下文中处理 and
或 or
。最简单的方法是使用 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 组:and
或 or
作为一个完整的词。
参见regex demo。
根据 "
和 '
在 "..."
和 '...'
中转义的方式,您需要调整正则表达式的 (?:\"[^\"]*\"|'[^']*')
部分.
~ ifelse(z=="or","|", "&")
部分是一个回调函数,它接收唯一的参数(在该函数中名为 z
),其内容是您从正则表达式中获得的匹配值(即 or
或 and
)。如果匹配值等于 or
,则匹配替换为 |
,否则替换为 &
.
正在尝试将 "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
值两边都被未加引号的单词包围。显然,这可能会在看到其他数据或更多嵌套内容时崩溃。
您应该考虑一种方法来匹配双引号和单引号子字符串以忽略它们,并且只在所有其他上下文中处理 and
或 or
。最简单的方法是使用 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 组:and
或or
作为一个完整的词。
参见regex demo。
根据 "
和 '
在 "..."
和 '...'
中转义的方式,您需要调整正则表达式的 (?:\"[^\"]*\"|'[^']*')
部分.
~ ifelse(z=="or","|", "&")
部分是一个回调函数,它接收唯一的参数(在该函数中名为 z
),其内容是您从正则表达式中获得的匹配值(即 or
或 and
)。如果匹配值等于 or
,则匹配替换为 |
,否则替换为 &
.