英文:
How to match a pattern multiple times within a string and replace them
问题
我想要找到所有在 #include 预处理指令中的 Foo 实例,使用正则表达式。到目前为止,我只能匹配一个实例,使用以下模式 #include "(.*?)Foo(.*?)"
,并将 Foo 替换为 Bar 我使用以下替换 #include "$1Bar$2"
。
当我将 Foo 替换为 Bar 时,以下示例
#include "abcFoo1/Foo123/aFoo"
变成了
#include "abcBar1/Foo123/aFoo"
我卡在尝试弄清如何使其匹配 #include 语句内的所有 Foo 实例并在替换后获得以下结果。
#include "abcBar1/Bar123/aBar"
P.S. 我试图在诸如 Notepad++ 或 Visual Studio 等文本编辑器中执行此操作,用于许多字符串。
英文:
I want to find all instances of Foo inside #include preprocessor using regex. so far, I can only match one instance using this pattern #include "(.*?)Foo(.*?)"
. and to replace Foo with Bar i use this substitution #include "$1Bar$2"
When I replace Foo with Bar, the following example
#include "abcFoo1/Foo123/aFoo"
becomes
#include "abcBar1/Foo123/aFoo"
I'm stuck trying to figure out how to make it match all instances of Foo within the #include statement and get the following result after replacement.
#include "abcBar1/Bar123/aBar"
P.S. I'm trying to do this for many strings using a text editor such as Notepad++ or IDE like Visual Studio.
答案1
得分: 2
以下是翻译好的部分:
您可以在例如Notepad++(或任何使用PCRE的工具)中使用此正则表达式,如果您想一次完成此操作:
(?:#include ".*?|(?<!^)\G.*?)\KFoo
解释:
(?:#include ".*?|(?<!^)\G.*?)
- 非捕获组,有两个备选项:
#include ".*?
- 您字符串的开头,后面跟着非贪婪匹配的任何内容。(?<!^)\G.*?
-\G
是前一次匹配结束的位置,后面跟着与上面相同的非贪婪匹配。在这里使用\G
是必要的,否则正则引擎不会匹配相同的部分两次。(?<!^)
是前行否定断言,用于不匹配在#include
之上有Foo
的情况(因为\G
从字符串的开头开始),这种情况不应该发生,可能是可选的,但为了完整的解决方案而包括在内。
\K
- 不要包括此之前的任何内容在匹配中,这样只有下一个部分会被匹配。Foo
- 您要替换的部分
我们只匹配Foo
,所以替换应该是Bar
。
此外,在Notepad++中,需要关闭“. matches newline
”选项。
英文:
You can use this regex in e.g. Notepad++ (or anything that uses PCRE) if you want to do it in one go:
(?:#include ".*?|(?<!^)\G.*?)\KFoo
Breakdown:
(?:#include ".*?|(?<!^)\G.*?)
- non-captured group with 2 alternatives:
#include ".*?
- the start of your string followed by non-greedily matched anything(?<!^)\G.*?
-\G
is the position at the end of previous match, followed by non-greedy anything as above. Using\G
is required here, since otherwise the regex engine won't match the same parts twice.(?<!^)
negative lookbehind of the start of the line is there to not match cases in which there would be something withFoo
above#include
s (as\G
starts at the start of the string), which shouldn't happen and is likely optional, but included it just in case, for a full solution.
\K
- don't include anything before this in the match, so that only the next part gets matchedFoo
- the part that you want to replace
We're matching only Foo
s, so the replacement should be just Bar
.
Also, in Notepad++, . matches newline
option needs to be turned off.
答案2
得分: 1
在Notepad++或Sublime Text中,您点击Ctrl+H,会弹出查找+替换栏,
您在查找字段中输入Foo,然后在替换字段中输入Bar,就可以了。
我相信不需要复杂的正则表达式模式。
英文:
On Notepad++ or Sublime text, you click Ctrl+H, you get the find+replace bar,
you write Foo in the find field, then Bar in the Replace, and it should be good.
no need for a complex regex pattern I believe.
答案3
得分: 0
Instead of looking for a string with Foo
to replace it with Bar
, look for Foo
which has #include
behind
(?=Foo)(?<=#include .*)Foo
or
Foo(?<=#include .*Foo)
英文:
Instead of looking for a string with Foo
to replace it with Bar
, look for Foo
which has #include
behind
(?=Foo)(?<=#include .*)Foo
or
Foo(?<=#include .*Foo)
答案4
得分: 0
如果文件名应该被双引号括起来,并且你不想匹配单独的双引号:
(?:#include\h+"(?=[^"\r\n]*")|\G(?!^))[^"\r\n]*?\KFoo
解释
(?:
非捕获组,用于提供多个替代项#include\h+"
匹配#include
后面跟着1个或多个水平空白字符(?=[^"\r\n]*")
正向预查,断言在同一行右边有一个"
|
或\G(?!^)
断言当前位置在前一次匹配的末尾,而不是字符串的开头
)
关闭非捕获组[^"\r\n]*?
匹配除了"
或换行符之外的可选字符\KFoo
忘记之前匹配的内容,然后匹配Foo
如果字符串不应该包含空格,你可以在否定字符类中使用 \s
:
(?:#include\h+"(?=[^"\s]*")|\G(?!^))[^"\s]*?\KFoo
英文:
If the filename should be between double quotes, and you don't want to match crossing a double quote by itself:
(?:#include\h+"(?=[^"\r\n]*")|\G(?!^))[^"\r\n]*?\KFoo
Explanation
(?:
Non capture group for the alternatives#include\h+"
Match#include
followed by 1+ horizontal whitespace chars(?=[^"\r\n]*")
Positive lookahead, assert a"
to the right on the same line|
Or\G(?!^)
Assert the current position at the end of the previous match, not at the start of the string
)
Close the non capture goru[^"\r\n]*?
Match optional chars other than"
or a newline\KFoo
Forget what is matches so far and matchFoo
If the string should not contain spaces, you can use \s
in the negated character class:
(?:#include\h+"(?=[^"\s]*")|\G(?!^))[^"\s]*?\KFoo
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论