使用perl将两个字符串之间的所有文本(包括换行符)替换掉。

13 浏览
0 Comments

使用perl将两个字符串之间的所有文本(包括换行符)替换掉。

我有几百个遵循特定格式的readme文件。我需要用不同的内容替换其中的一段文字。除了在单词之间有换行符`\n`时无法选择这些单词之外,一切都运行得很顺利。一个例子如下:

...
this
is
old
content
...

我想要替换这些文件中的所有文本,使其看起来像这样:

...
new content
...

我尝试过以下的perl命令,但它们无法处理换行符:

perl -pi -w -e 's/this(\n|.)*?content/new content/g;' *.txt

我尝试根据https://stackoverflow.com/a/226601/4975772中的建议添加了`/s`标签(也许我操作错误..)

perl -pi -w -e 's/this(\n|.)*?content/new content/gs;' *.txt

去掉`?`后:

perl -pi -w -e 's/this(\n|.)*content/new content/g;' *.txt

根据Regex to match any character including new lines,使用`(.+?)`而不是`(\n|.)`:

perl -pi -w -e 's/this(.+?)*content/new content/g;' *.txt

根据Regex to match any character including new lines,使用`[\s\S]`而不是`(\n|.)`:

perl -pi -w -e 's/this[\s\S]*content/new content/g;' *.txt

我在regexpal.com上尝试了这些表达式,据说它们完美地工作。

regexpal example

如果我从readme文件中删除换行符,所有这些perl命令都能完美工作。我做错了什么?

0
0 Comments

问题的出现原因是使用Perl编写的正则表达式替换命令无法替换两个字符串之间的所有文本,包括换行符。

解决方法是使用Perl的-slurp模式(即0777),该模式将整个文件传递给脚本的$_变量。这相当于在代码中使用local $/;来读取整个文件内容。

以下是解决方法的代码示例:

perl -0777 -pi -e 's/this.*?content/new content/sg;' *.txt

在这个示例中,0777是slurp模式的参数。它将整个文件传递给脚本的$_变量。

示例中的正则表达式是s/this.*?content/new content/sg,它将匹配thiscontent之间的任意文本,并用new content替换。

使用s修饰符允许.匹配包括换行符在内的任意字符。

通过在命令行中使用-pi选项,可以将替换结果写回原始文件。

这样,无论文件中是否有换行符,都可以正确替换两个字符串之间的所有文本。

0