我需要从R中的SQL语句字符串中删除以--
开头的注释。我正在尝试使用正则表达式和gsub
(尽管我对其他建议持开放态度)。复杂的是,字符串可以包含以--->>>
开头并以<<<---
结尾的特殊标记,我需要将其保留以供进一步处理。
使用lookaheads和lookbehinds,我从那行开头的那些评论/标签取得了一些进展:
> re <- "^(?!=<<<-){1}--(?!->>>){1}.*$"
>
> gsub(re, "", "-- test", perl=TRUE) # should be ""
[1] ""
> gsub(re, "", "--->>> test", perl=TRUE) # should be "--->>> test"
[1] "--->>> test"
> gsub(re, "", "<<<--- test", perl=TRUE) # should be "<<<--- test"
[1] "<<<--- test"
> gsub(re, "", "--->>>->>> test", perl=TRUE) # should be --->>>->>> test
[1] "--->>>->>> test"
> gsub(re, "", "---->>> test", perl=TRUE) # should be ""
[1] ""
> gsub(re, "", "test --->>> test", perl=TRUE) # should be "test --->>> test"
[1] "test --->>> test"
> gsub(re, "", "test --->>> test <<<---", perl=TRUE) # should be "test --->>> test <<<---"
[1] "test --->>> test <<<---"
但是,这显然不适用于字符串中其他地方的注释:
> gsub(re, "", "test1 -- test", perl=TRUE) # should be "test1"
[1] "test1 -- test" # WRONG
删除正则表达式开头的^
会破坏大多数测试用例:
> re <- "(?!=<<<-){1}--(?!->>>){1}.*$"
> gsub(re, "", "-- test", perl=TRUE) # should be ""
[1] ""
> gsub(re, "", "test1 -- test", perl=TRUE) # should be "test1"
[1] "test1 "
> gsub(re, "", "--->>> test", perl=TRUE) # should be "--->>> test"
[1] "-" # WRONG
> gsub(re, "", "<<<--- test", perl=TRUE) # should be "<<<--- test"
[1] "<<<" # WRONG
> gsub(re, "", "--->>>->>> test", perl=TRUE) # should be --->>>->>> test
[1] "-" # WRONG
> gsub(re, "", "---->>> test", perl=TRUE) # should be ""
[1] ""
> gsub(re, "", "test --->>> test", perl=TRUE) # should be "test --->>> test"
[1] "test -" # WRONG
> gsub(re, "", "test --->>> test <<<---", perl=TRUE) # should be "test --->>> test <<<---"
[1] "test -" # WRONG
任何人都有建议我怎么做?我对任何建议持开放态度,但我受限于R并且必须保留特殊标记--->>>
和<<<---
。
修改
正如评论中所提到的,这也是一个测试案例:
> gsub(re, "", "-->>> test", perl=TRUE) # should be ""
答案 0 :(得分:3)
我发布了我在评论中分享的表达,因为它结果很有帮助。它背后的想法是我们可以匹配特定的子串,然后从匹配中丢弃它们,并且仅使用(*SKIP)(*FAIL)
动词之后的模式部分匹配并保留我们想要删除的内容。
使用
(?:(?<!-)--->>>|<<<---(?!-))(*SKIP)(*FAIL)|--.*
我们匹配以下内容:
(?:(?<!-)--->>>|<<<---(?!-))(*SKIP)(*FAIL)
- 两个序列中的任何一个:
(?<!-)--->>>
- --->>>
之前没有-
|
- 或<<<---(?!-)
- <<<---
未跟随-
(*SKIP)(*FAIL)
- 放弃到目前为止匹配的内容并继续下一场比赛|
- 或--.*
- 2个连字符后跟0 +字符而不是换行符请参阅regex demo at regex101.com。
注意专用解析器可以更加安全。
答案 1 :(得分:1)