Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 以预先发现的模式替换正则表达式(两步过程)_Regex_Perl - Fatal编程技术网

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\ /\/