String 在Perl中如何在字符串中包含新行?
我有一根像这样的线String 在Perl中如何在字符串中包含新行?,string,perl,newline,String,Perl,Newline,我有一根像这样的线 Acanthocolla_cruciata,#8B5F65Acanthocyrta_haeckeli,#8B5F65Acanthometra_fusca,#8B5F65Acanthopeltis_japonica,#FFB5C5 我正在尝试添加新行,所以请使用列表格式。像这样 Acanthocolla_cruciata,#8B5F65 Acanthocyrta_haeckeli,#8B5F65 Acanthometra_fusca,#8B5F65 Acanthopeltis
Acanthocolla_cruciata,#8B5F65Acanthocyrta_haeckeli,#8B5F65Acanthometra_fusca,#8B5F65Acanthopeltis_japonica,#FFB5C5
我正在尝试添加新行,所以请使用列表格式。像这样
Acanthocolla_cruciata,#8B5F65
Acanthocyrta_haeckeli,#8B5F65
Acanthometra_fusca,#8B5F65
Acanthopeltis_japonica,#FFB5C5
我有一个perl脚本
use strict;
use warnings;
open my $new_tree_fh, '>', 'test_match.txt'
or die qq{Failed to open "update_color.txt" for output: $!\n};
open my $file, '<', $ARGV[0]
or die qq{Failed to open "$ARGV[0]" for input: $!\n};
while ( my $string = <$file> ) {
my $splitmessage = join ("\n", ($string =~ m/(.+)+\,+\#+\w{6}/gs));
print $new_tree_fh $splitmessage, "\n";
}
close $file;
close $new_tree_fh;
使用严格;
使用警告;
打开我的$new_tree_fh,'>','test_match.txt'
或死qq{无法打开“update_color.txt”进行输出:$!\n};
打开我的$file,“好吧,我想这里的问题是正则表达式不匹配
(.+)+
例如-可能不会做你认为它会做的事情。这是一个贪婪的捕获一个或多个“任何东西”,这将抓住你的整个字符串
请在上查看
尝试:
我会:
my $str = 'Acanthocolla_cruciata,#8B5F65Acanthocyrta_haeckeli,#8B5F65Acanthometra_fusca,#8B5F65Acanthopeltis_japonica,#FFB5C5';
$str =~ s/(?<=,#\w{6})/\n/g;
say $str;
与其说是快速修复解决方案,不如让我们在现有代码中找到问题所在,并从中学习。您的问题在正则表达式中,因此我们将对其进行剖析并修复
($string =~ m/(.+)+\,+\#+\w{6}/gs)
- 首先,导致错误的两个重要错误:
- 开始时,您要执行一个
+
,然后匹配、
和#
等等。问题是,+
是贪婪的,这意味着它将匹配到输入中最后一个,
,而不是第一个。因此,当您运行此操作时,几乎整个生产线(除了最后一种植物的颜色)都会与此单一的+
有几种不同的方法可以解决这个问题,但最简单的方法是限制匹配的内容。而不是说<代码> ++/COD>“匹配任何东西”,在开始时把它定义为<代码> [\W\s] +<代码>,这意味着匹配“Word字符”(包括字母和数字)或空格字符(因为在工厂名称中间有一个空格)。
($string=~m/([\w\s]+)+\,++\w{6}/gs)
这会更改输出,但仍然不是完全正确的版本,因为:
m/some regex/g
将其匹配项列表作为列表返回,我们希望它返回整个匹配项,包括植物名称和颜色。但是,当匹配项中的任意位置存在偏执时,m/
只返回与偏执匹配的部分(此处为植物名称),而不是整个匹配项。因此,去掉偏执,它就变成:
($string=~m/[\w\s]++\,++\w{6}/gs)
这是可行的,但相当笨拙且容易出现错误,因此这里有一些改进建议:
- 由于您的输入没有换行符,因此不需要结尾的/s。
($string=~m/[\w\s]++\,++\w{6}/g)
、
和#
在perl正则表达式中不是特殊字符,因此它们前面不需要\
。
($string=~m/[\w\s]++,++\w{6}/g)
+
用于只知道角色会出现,但不知道会出现多少次的情况。在这里,由于我们只尝试匹配一个、
和一个#
字符,因此它们后面的+
是不必要的。
($string=~m/[\w\s]+,#\w{6}/g)
- [\w\s]之后的
+
表示与+
完全不同的内容(基本上比通常更贪婪),因此让我们将其设为一个+
($string=~m/[\w\s]+,#\w{6}/g)
- 或者,您可以更改最后一个
\w
以仅匹配将出现在颜色代码中的十六进制字符:
($string=~m/[\w\s]+,#[0-9A-F]{6}/g)
这是一个非常可靠的、可以正常工作的正则表达式,可以满足您的需要 我不确定你的模式匹配在那里是否有效。您正在对(.+)
使用贪婪捕获,这将占用大部分字符串。
my $str = 'Acanthocolla_cruciata,#8B5F65Acanthocyrta_haeckeli,#8B5F65Acanthometra_fusca,#8B5F65Acanthopeltis_japonica,#FFB5C5';
$str =~ s/(?<=,#\w{6})/\n/g;
say $str;
Acanthocolla_cruciata,#8B5F65
Acanthocyrta_haeckeli,#8B5F65
Acanthometra_fusca,#8B5F65
Acanthopeltis_japonica,#FFB5C5
($string =~ m/(.+)+\,+\#+\w{6}/gs)