Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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 Perl:将模式从当前位置替换到行尾_Regex_Perl_Replace - Fatal编程技术网

Regex Perl:将模式从当前位置替换到行尾

Regex Perl:将模式从当前位置替换到行尾,regex,perl,replace,Regex,Perl,Replace,在中,如何替换从当前位置(上次替换的位置)到行尾的图案 我在一行中完成了所有这些替换: ... s/\[//; s/(\/\w\w\w\/)/ getMonth $1 /e; s/:/ /; s/\s\+\d\d\d\d\]//; #NOW: replace all blanks with a plus sign from this position until the end of this line. 从Perl 5.6开始,最后一次匹配结束时的位置存储在@+数组中。整个匹配结束时的位置是

在中,如何替换从当前位置(上次替换的位置)到行尾的图案

我在一行中完成了所有这些替换:

...
s/\[//;
s/(\/\w\w\w\/)/ getMonth $1 /e;
s/:/ /;
s/\s\+\d\d\d\d\]//;
#NOW: replace all blanks with a plus sign from this position until the end of this line.

从Perl 5.6开始,最后一次匹配结束时的位置存储在
@+
数组中。整个匹配结束时的位置是
$+[0]

您可以使用此选项将字符串拆分为两部分,并仅对后面的部分进行替换:

my $base = " pears apples bananas coconuts ";
$base =~ s/apples/oranges/;
my $firstpart = substr($base, 0, $+[0]);
my $secondpart = substr($base, $+[0]); 
$secondpart =~ s/ /\+/g;
print '"' . $firstpart . $secondpart . "\"\n";
将打印:

" pears oranges+bananas+coconuts+"

这种方法的一个问题是
$+[0]
包含替换前的位置。所以也许有更好的办法:)我看你已经接受了答案。然而,对于手头的任务,使用或可能使用以下方法更合适:

Apache::LogRegex
-将Apache日志文件中的一行解析为散列

在我看来,您正试图从头开始编写日志文件分析器,这是您按月对日志文件条目进行分组的方法。如果是这样,请停止重新发明方轮

即使您不想使用外部模块,也可以通过使用以下方法来划分和征服任务:

输出:

62.174.188.166--Mar“GET+/puntos/img/ganar.gif+HTTP/1.1”+200+1551+”http://www
.universia.com/puntos/index.jsp”+“Mozilla/4.0+(兼容;+MSIE+5.0;+Windows+98

;+DigExt;+Hotbar+2.0)“

从您的语言中,您似乎在想象您的替换序列正在通过字符串向前推进,每个替换都在最后一个替换停止的地方进行。事实上,每个替换都将应用于整个字符串

当你说“最后一次替换的位置”时,如果之前的替换没有发现什么,会发生什么

在脚本中,您只需执行以下操作:

if ( s/\s\+\d\d\d\d\]// ) { $' =~ s/ /+/g }
但在可重用代码中应避免使用$,因为它会影响其他正则表达式的性能。好了,你需要这样做

if ( s/\s\+\d\d\d\d\]// ) { substr($_, $+[0]) =~ s/ /+/g }

但是在任何一种情况下,您都需要确保您希望设置为$'或@+的匹配或替换实际成功。

请给出一个示例,说明您正在执行这些操作的输入。
s//
操作。这是一个web服务器日志行,我的代码示例中没有包含所有替换。62.174.188.166--[01/Mar/2003:00:00:00+0100]“GET/puntos/img/ganar.gif HTTP/1.1”200 1551““Mozilla/4.0(兼容;MSIE 5.0;Windows 98;DigExt;Hotbar 2.0)”替换OP的这一系列
s//
操作会好得多(似乎是这样说的“将方括号中的月+年替换为
getMonth
returns”)简化的操作更加简洁,并允许满足其余的要求。但是,这需要OP的合作。
$++
不是数组。
@++
是数组。我更正了您的错误并链接到文档中的正确位置。回滚这些事实更正(你可以很容易地证实)是不对的。@SinanÜnür:如果你添加评论,如果我同意,我可以编辑我的答案(在这里完成)@Andomar:如果您对由其他受信任的用户编辑您的问题和答案的想法感到不舒服,那么这个网站可能不适合您。请参阅,试图强加一个要求,要求其他人在修复错误之前获得您的批准,这与SO的精神背道而驰。@Andomar:在描述语言时,您真的更喜欢perl而不是perl吗e、 还是这对你来说只是一场激烈的比赛?“这是最后一个替换者的位置,
\s\+\d\d\d
匹配。如果你知道比
$+[0]
更好的方法,请发布:)@安德奥马尔:对不起,我没有很好地理解这个问题;完全替换了我的答案+1,
s/*/+/
应该是
s//+/+/g
,但是很高兴看到substr上的替换更改了原来的字符串啊,再次误读了你。修复了。y/+//也可以。
if ( s/\s\+\d\d\d\d\]// ) { substr($_, $+[0]) =~ s/ /+/g }