如何在 Perl 中的字符串中包含新行?
How do I include new lines in a string in Perl?
我有一个看起来像这样的字符串
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;
模式匹配有效,但它不会打印新行,因为我想制作列表。任何人都可以提出任何建议。
好的,我认为你的问题是你的正则表达式匹配不正确。
(.+)+
例如 - 可能并不像您认为的那样。这是对 "anything" 中 1 个或多个的贪婪捕获,这将捕获您的整个字符串。
在 regex101 上查看。
尝试:
#!/usr/bin/perl
use strict;
use warnings;
while ( my $string = <DATA> ) {
my $splitmessage = join( "\n", ( $string =~ m/(\w+,\#+\w{6})/g ) );
print $splitmessage, "\n";
}
__DATA__
Acanthocolla_cruciata,#8B5F65Acanthocyrta_haeckeli,#8B5F65Acanthometra_fusca,#8B5F65Acanthopeltis_japonica,#FFB5C5
将打印:
Acanthocolla_cruciata,#8B5F65
Acanthocyrta_haeckeli,#8B5F65
Acanthometra_fusca,#8B5F65
Acanthopeltis_japonica,#FFB5C5
我愿意:
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)
首先,导致错误的两个重大错误:
一开始,你在做一个.+
,然后匹配,
和#
等等。问题是,.+
是贪心的,这意味着它将匹配输入中的 last ,
,而不是第一个。所以当你 运行 这个时,几乎整行(除了最后一种植物的颜色)都与这个 .+
.
相匹配
有几种不同的方法可以解决此问题,但最简单的方法是限制要匹配的内容。不要说 .+
"match anything",而是在开头写成 [\w\s]+
- 这意味着匹配 "word characters"(包括字母和数字)或 space 个字符(因为植物名中间有个space。
($string =~ m/([\w\s]+)+\,+\#+\w{6}/gs)
这改变了输出,但仍然不是完全正确的版本,因为:
m/some regex/g
returns 其匹配列表作为列表,我们想要的是 return 整个匹配包括植物名称和颜色。但是,当匹配中任何地方有括号时,m/
return只是括号匹配的部分(这里是植物名),而不是整个匹配。所以,去掉括号,它变成:
($string =~ m/[\w\s]++\,+\#+\w{6}/gs)
这可行,但非常笨拙且容易出错,因此这里有一些改进建议:
- 由于您的输入没有换行符,所以末尾的 /s 是不必要的。
($string =~ m/[\w\s]++\,+\#+\w{6}/g)
,
和 #
不是 perl 正则表达式中的特殊字符,因此它们前面不需要 \
。
($string =~ m/[\w\s]++,+#+\w{6}/g)
+
适用于您只知道该字符会出现但不知道会出现多少次的情况。在这里,由于我们只尝试匹配 one ,
和 one #
字符,因此 +
在他们之后是不必要的。
($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)
这是一个非常可靠、有效的正则表达式,可以满足您的需求。
我有一个看起来像这样的字符串
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;
模式匹配有效,但它不会打印新行,因为我想制作列表。任何人都可以提出任何建议。
好的,我认为你的问题是你的正则表达式匹配不正确。
(.+)+
例如 - 可能并不像您认为的那样。这是对 "anything" 中 1 个或多个的贪婪捕获,这将捕获您的整个字符串。
在 regex101 上查看。
尝试:
#!/usr/bin/perl
use strict;
use warnings;
while ( my $string = <DATA> ) {
my $splitmessage = join( "\n", ( $string =~ m/(\w+,\#+\w{6})/g ) );
print $splitmessage, "\n";
}
__DATA__
Acanthocolla_cruciata,#8B5F65Acanthocyrta_haeckeli,#8B5F65Acanthometra_fusca,#8B5F65Acanthopeltis_japonica,#FFB5C5
将打印:
Acanthocolla_cruciata,#8B5F65
Acanthocyrta_haeckeli,#8B5F65
Acanthometra_fusca,#8B5F65
Acanthopeltis_japonica,#FFB5C5
我愿意:
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)
首先,导致错误的两个重大错误:
一开始,你在做一个
.+
,然后匹配,
和#
等等。问题是,.+
是贪心的,这意味着它将匹配输入中的 last,
,而不是第一个。所以当你 运行 这个时,几乎整行(除了最后一种植物的颜色)都与这个.+
.
相匹配 有几种不同的方法可以解决此问题,但最简单的方法是限制要匹配的内容。不要说.+
"match anything",而是在开头写成[\w\s]+
- 这意味着匹配 "word characters"(包括字母和数字)或 space 个字符(因为植物名中间有个space。
($string =~ m/([\w\s]+)+\,+\#+\w{6}/gs)
这改变了输出,但仍然不是完全正确的版本,因为:m/some regex/g
returns 其匹配列表作为列表,我们想要的是 return 整个匹配包括植物名称和颜色。但是,当匹配中任何地方有括号时,m/
return只是括号匹配的部分(这里是植物名),而不是整个匹配。所以,去掉括号,它变成:
($string =~ m/[\w\s]++\,+\#+\w{6}/gs)
这可行,但非常笨拙且容易出错,因此这里有一些改进建议:
- 由于您的输入没有换行符,所以末尾的 /s 是不必要的。
($string =~ m/[\w\s]++\,+\#+\w{6}/g)
,
和#
不是 perl 正则表达式中的特殊字符,因此它们前面不需要\
。
($string =~ m/[\w\s]++,+#+\w{6}/g)
+
适用于您只知道该字符会出现但不知道会出现多少次的情况。在这里,由于我们只尝试匹配 one,
和 one#
字符,因此+
在他们之后是不必要的。
($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)
这是一个非常可靠、有效的正则表达式,可以满足您的需求。