Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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 如何替换字符串的中间部分? $a=“3232” $a=~s/(.*)/000/gi;_Regex_Perl - Fatal编程技术网

Regex 如何替换字符串的中间部分? $a=“3232” $a=~s/(.*)/000/gi;

Regex 如何替换字符串的中间部分? $a=“3232” $a=~s/(.*)/000/gi;,regex,perl,Regex,Perl,我希望$a变成“000”,但它不起作用。首先,/in被解释为模式的结尾,这会导致语法错误。为替换运算符选择不同的分隔符: $a = "<no> 3232 </no> " $a =~ s/<no>(.*)</no>/000/gi ; s|.*000|gi; 但是你有一组捕获括号,你没有使用它们捕获的内容。这让我觉得,即使修改语法也不会给你想要的行为。您不想替换标记,因此可以将这些标记添加到替换中: s|<no>.*</no&g

我希望
$a
变成
“000”
,但它不起作用。

首先,/in被解释为模式的结尾,这会导致语法错误。为替换运算符选择不同的分隔符:

$a = "<no> 3232 </no> "

$a =~ s/<no>(.*)</no>/000/gi ;
s|.*000|gi;
但是你有一组捕获括号,你没有使用它们捕获的内容。这让我觉得,即使修改语法也不会给你想要的行为。您不想替换标记,因此可以将这些标记添加到替换中:

s|<no>.*</no>|000|gi;
s|.*000|gi;
或者根本不使用lookarounds替换它们,这样它们就不是匹配文本的一部分:

s|<no>.*</no>|<no>000</no>|gi;

s |(?如果您只想替换标记之间的文本,那么您可能需要查看。并且您需要使用除“/”之外的正则表达式分隔符或转义正则表达式中的“/”:

s|(?<=<no>).*(?=</no>)|000|gi;
$a=“3232”;
$a=~s#(?你需要的


$a=~s |(?您可以放弃花哨的lookahead或lookaround断言,而使用稍长的正则表达式:

$a =~ s|(?<=<no> ).*(?= </no>)|000|gi;
# $a is now "<no> 000 </no> "
$str=~s |.*000 | gi;

它可能更容易阅读,但这有点违反直觉,因为你用
000
替换
任何东西,也就是说,你不仅仅是替换
之间的东西,而是用另一个字符串替换整个字符串,而这个字符串恰好包含

首先y、 结尾处的/被视为正则表达式的结束引号。请将其反斜杠:

$str =~ s|<no>.*?</no>|<no>000</no>|gi;
由于这仍然会替换
,因此您可能需要将它们放回:

$a =~ s~<no>(.*?)</no>~000~gi;
这可能和你解决这个问题的效率一样

另一方面,尝试用正则表达式解析XML通常是一个坏主意,因为对于正则表达式来说,XML太多了,无法解析。我非常喜欢
XML::LibXML
来处理XML文档,但这并不是一件容易的事。但是,如果您对XML的精确格式有信心(或者事实上它不是XML,只是看起来有点像它)那么正则表达式就可以作为一种本地黑客

这一切都在
perlre
手册页中介绍过,如果您想用Perl正则表达式做任何事情,即使是非常琐碎的事情,也必须阅读该手册

$a =~ s~(<no>).*?(</no>)~$1000$2~gi;

希望所有的例子都有助于澄清问题。

为了尽可能简单,你有很多问题,所以让我们先排除那些显而易见的问题

首先,不能在字符串中单独使用斜杠字符(“
/
”),因为它对per有特殊意义;例如“
/n
”表示打印新行,斜杠也用于分隔正则表达式的部分。当您想使用斜杠作为文本时,解决方案是用反斜杠转义斜杠,告诉perl您确实需要斜杠字符而不是特殊字符。因此,您的原始代码最好是这样编写:

$ perldoc perlre
$a = "<no> 3232 <\/no> ";
$a =~ s/(<no>).*(<\/no>)/$1 000$2/gi;
$a=“3232”;
$a=~s/(.*)/000/gi;
现在perl将
解释为

其次,您的正则表达式是错误的。s///regex指示perl用第二节中的模式替换/重新格式化第一节中的模式。您的指令告诉perl用“000”替换前两个斜杠之间的所有内容,并将其分配给变量$a

您在正则表达式中使用的括号允许您将表达式拆分为多个片段并重新排列内容,但您没有使用它们,但您走的是正确的道路。要重复使用第一组斜杠中要保留的表达式部分,请在其周围放置括号。在表达式的第二部分,您可以引用通过使用$1、$2等来指代每组括号内的内容,将这些“片段”转换为“片段”

记住这一点,你可能会想出来一些东西,比如:

$a = "<no> 3232 <\/no> ";
$a =~ s/<no>(.*)<\/no>/000/gi;
$a=“3232”;
$a=~s/()。*()/$1000$2/gi;
正如上面所建议的那样,这很接近,但测试将表明它仍然不完全正确;更令人困惑的是,这次您将得到的输出是
。这是因为perl将字符串解释为$1000后跟$2,而$1000不引用任何内容。在$1后面加空格或其他内容将纠正此问题。(也许有某种方法可以更准确地终止1美元,但我在这里承认我不知道。)

下面的表达式起作用,但在第一个表达式之后会有一个空格,因此输出将是
000

$a=“3232”;
$a=~s/()*()/$1000$2/gi;
我的首选是使用变量代替字符串“000”,因此我的代码可能如下所示:

$ perldoc perlre
$a = "<no> 3232 <\/no> ";
$a =~ s/(<no>).*(<\/no>)/$1 000$2/gi;
$a=“3232”;
$b=“000”;
$a=~s/()*?()/$1$b$2/gi;

在我看来,使用一个变量可以让事情更清楚一些(尽管它们可以更好地命名!),而且还允许替换的文本(“000”)可以很容易地更改,而不必弄乱正则表达式“如果字符串中有多组no元素,则贪婪-这会导致。*遇到匹配模式时立即停止匹配,在本例中为”。

您所说的“它不工作”是什么意思?您会遇到什么错误?它将所有字符串替换为000这是一种隐藏的“如何修改XML文档中的值”吗?”问题?@Tree:不,它不会取代任何东西。这是一个语法错误。人们通常不喜欢通过链接到初学者手册中显而易见的部分来回答的问题。通过谷歌搜索Perl正则表达式,你会发现
perldoc perlre
可能会帮你解决问题。StackOverflow是你阅读后的最佳选择我做过这样的研究,但还是发现自己在t
$ perldoc perlre
$a = "<no> 3232 <\/no> ";
$a =~ s/<no>(.*)<\/no>/000/gi;
$a = "<no> 3232 <\/no> ";
$a =~ s/(<no>).*(<\/no>)/$1000$2/gi;
$a = "<no> 3232 <\/no> ";
$a =~ s/(<no>).*(<\/no>)/$1 000$2/gi;
$a = "<no> 3232 <\/no> ";
$b = "000";
$a =~ s/(<no>).*?(<\/no>)/$1$b$2/gi;