Regex 以预先发现的模式替换正则表达式(两步过程)
我想用Regex 以预先发现的模式替换正则表达式(两步过程),regex,perl,Regex,Perl,我想用/替换\include指令中的所有\。我想一次完成。不幸的是,我只找到了几行: if(/^\s*#include\s*(?:"|<)\K.*\\.*(?="|>)/) { my $r = $& =~ s|\\|/|gr; s/\Q$&\E/$r/g; } 并获得: #include ".../.../foo/bar.c" /* Here */// a \comment\ /\/ 我能把它做得更好、更漂亮、更短吗?从命令行使用perl pe
/
替换\include
指令中的所有\
。我想一次完成。不幸的是,我只找到了几行:
if(/^\s*#include\s*(?:"|<)\K.*\\.*(?="|>)/) {
my $r = $& =~ s|\\|/|gr;
s/\Q$&\E/$r/g;
}
并获得:
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/
我能把它做得更好、更漂亮、更短吗?从命令行使用perl
perl -i pe 's{^\s*\#include\s*[<"]+\K ([^">]+) (?=[">]+)}{ $1 =~ y|\\|/|r }xe' file
这可以通过以下方式实现。锚点
\G
在上次匹配结束的位置匹配。在第一次匹配尝试期间,\G
以\A
的方式在字符串开头匹配
$ echo ' #include "...\...\foo\bar.c" /* Here */// a \comment\ /\/' | perl -pe 's~(?:^\s*#include\s*"|\G)[^\\"]*\K\\~/~g'
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/
$ echo ' #include "...\...\foo\bar.c" /* Here */// a \comment\ /\/' | perl -pe 's~(?:^\s*#include\s*"|\G)[^\\"]*\K\\(?=[^"]*")~/~g'
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/
对于这两种情况,一个班轮应该是
$ echo '#include "...\...\foo\bar.c" /* Here */// a \comment\ /\/ "foo\bar"
#include <...\...\foo\bar.c> foo\\bar' | perl -pe 's~(?:(?:^\s*#include\s*"|\G)[^\\">]*\K\\)|(?:(?:^\s*#include\s*<|\G)[^\\><]*\K\\(?=[^<>]*>))~/~g'
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/ "foo\bar"
#include <.../.../foo/bar.c> foo\\bar
$echo'#包括“…\…\foo\bar.c”/*此处*///a\comment\/\//“foo\bar”
#include foo\\bar'|perl-pe's~(?:(?:^\s*#include\s*|“|\G)[^\\\”>]*\K\\)|(?:(?:^\s*#include\s*)~/~G'
#包括“..../foo/bar.c”/*此处*///a\comment\//\//“foo\bar”
#包含foo\\bar
我建议您将@-
和+
数组与substr
一起使用,以便仅将翻译应用于所需的部分。(请参见中的@LAST\u MATCH\u START
和@LAST\u MATCH\u END
)
像这样
use strict;
use warnings;
use 5.010;
my $s = '#include "...\...\foo\bar.c" /* Here */// a \comment\ /\/';
say $s;
if ( $s =~ / \#include \s* ( "[^"]+" | <[^>]+> ) /x ) {
substr($s, $-[1], $+[1]-$-[1]) =~ tr|\\|/|;
}
say $s;
上述输入的预期输出是什么?
tr |\\\\\\\\/|如果/#包含/
,是否有任何错误?@Borodin是,它将用/comment/
更改注释中的\comment\:(如果分隔符是
?好的,但这应该是你的答案。@AvinashRaj最好把它放在一个新的regex101会话中,因为如果我点击你的演示链接,我会因为“旧版本”警告而临时转到最新版本。[]+
不应该只是[]
?我想我更喜欢s。){^s*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。
$ echo ' #include "...\...\foo\bar.c" /* Here */// a \comment\ /\/' | perl -pe 's~(?:^\s*#include\s*"|\G)[^\\"]*\K\\~/~g'
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/
$ echo ' #include "...\...\foo\bar.c" /* Here */// a \comment\ /\/' | perl -pe 's~(?:^\s*#include\s*"|\G)[^\\"]*\K\\(?=[^"]*")~/~g'
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/
$ echo '#include "...\...\foo\bar.c" /* Here */// a \comment\ /\/ "foo\bar"
#include <...\...\foo\bar.c> foo\\bar' | perl -pe 's~(?:(?:^\s*#include\s*"|\G)[^\\">]*\K\\)|(?:(?:^\s*#include\s*<|\G)[^\\><]*\K\\(?=[^<>]*>))~/~g'
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/ "foo\bar"
#include <.../.../foo/bar.c> foo\\bar
use strict;
use warnings;
use 5.010;
my $s = '#include "...\...\foo\bar.c" /* Here */// a \comment\ /\/';
say $s;
if ( $s =~ / \#include \s* ( "[^"]+" | <[^>]+> ) /x ) {
substr($s, $-[1], $+[1]-$-[1]) =~ tr|\\|/|;
}
say $s;
#include "...\...\foo\bar.c" /* Here */// a \comment\ /\/
#include ".../.../foo/bar.c" /* Here */// a \comment\ /\/