在 Perl 中使用正则表达式在两个字符串之间提取字符串
Extract string between two strings using Regexp in Perl
我尝试在 Perl 中提取 [%L10n.msg('
和 ')%]
之间的文本,例如,如果我有像 [%L10n.msg('foo')%]
这样的代码,我想得到 foo .
我有它的工作脚本,正如您在下面看到的那样,但是它有问题并且破坏了编码,如您所见。
我想知道该脚本有什么问题以及如何修复它。
我的正则表达式脚本:
my (@L10n) = $content_from_file =~ /\[\%L10n\.msg\('(.*)'\)\%\]/g;
$content_from_file:
<div class="detail-trash">
<span class="blog-article-social-net social-net-fb">
<svg class="svg-icon-facebook">
<use xlink:href="[%domain.url_media%]/images/svg-sprite.svg#svg-icon-facebook"></use>
</svg>
[%L10n.msg('Zdielať')%]
</span>
<span class="previews-counter">Počet hodnotení: [%product.rating_votes%]</span>
<a href="#" title="[%L10n.msg('Zobraziť recenzie')%]" class="previews-btn js-previews-btn">[%L10n.msg('Zobraziť recenzie')%]</a>
</div>
当前结果:
Zdiela\x{165}
Zobrazi\x{165} recenzie')%]\" class=\"previews-btn js-previews-btn\">[%L10n.msg('Zobrazi\x{165} recenzie
请求结果:
Zdielať
Zobraziť recenzie
Zobraziť recenzie
在正则表达式中 .*
是贪婪的。这意味着它将尝试匹配最长的字符串。
改成.*?
这样就不贪心了。然后它将匹配最短的字符串。
my @L10n = $content_from_file =~ /\[%L10n\.msg\('(.*?)'\)%\]/g;
我为你创建了这个正则表达式
(?:\[%L10n.msg\(')([A-Za-zť ]+)
它符合您的需要,但如果是斯洛伐克字符,您可能需要调整一下?
结果在group1
你可以看这里
解决匹配问题的最简单方法是使正则表达式的 .*
部分成为非贪婪的,方法是在末尾添加 ?
。
您的编码问题更难解决,因为它取决于数据文件的编码以及您将数据读入文件的方式。所以我们需要更多信息。
这个版本适合我:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $content_from_file = <<END_OF_TXT;
<div class="detail-trash">
<span class="blog-article-social-net social-net-fb">
<svg class="svg-icon-facebook">
<use xlink:href="[%domain.url_media%]/images/svg-sprite.svg#svg-icon-facebook"></use>
</svg>
[%L10n.msg('Zdielať')%]
</span>
<span class="previews-counter">Počet hodnotení: [%product.rating_votes%]</span>
<a href="#" title="[%L10n.msg('Zobraziť recenzie')%]" class="previews-btn js-previews-btn">[%L10n.msg('Zobraziť recenzie')%]</a>
</div>
END_OF_TXT
my (@L10n) = $content_from_file =~ /\[\%L10n\.msg\('(.*?)'\)\%\]/g;
say Dumper @L10n;
输出:
$VAR1 = 'Zdielať';
$VAR2 = 'Zobraziť recenzie';
$VAR3 = 'Zobraziť recenzie';
我尝试在 Perl 中提取 [%L10n.msg('
和 ')%]
之间的文本,例如,如果我有像 [%L10n.msg('foo')%]
这样的代码,我想得到 foo .
我有它的工作脚本,正如您在下面看到的那样,但是它有问题并且破坏了编码,如您所见。
我想知道该脚本有什么问题以及如何修复它。
我的正则表达式脚本:
my (@L10n) = $content_from_file =~ /\[\%L10n\.msg\('(.*)'\)\%\]/g;
$content_from_file:
<div class="detail-trash">
<span class="blog-article-social-net social-net-fb">
<svg class="svg-icon-facebook">
<use xlink:href="[%domain.url_media%]/images/svg-sprite.svg#svg-icon-facebook"></use>
</svg>
[%L10n.msg('Zdielať')%]
</span>
<span class="previews-counter">Počet hodnotení: [%product.rating_votes%]</span>
<a href="#" title="[%L10n.msg('Zobraziť recenzie')%]" class="previews-btn js-previews-btn">[%L10n.msg('Zobraziť recenzie')%]</a>
</div>
当前结果:
Zdiela\x{165}
Zobrazi\x{165} recenzie')%]\" class=\"previews-btn js-previews-btn\">[%L10n.msg('Zobrazi\x{165} recenzie
请求结果:
Zdielať
Zobraziť recenzie
Zobraziť recenzie
在正则表达式中 .*
是贪婪的。这意味着它将尝试匹配最长的字符串。
改成.*?
这样就不贪心了。然后它将匹配最短的字符串。
my @L10n = $content_from_file =~ /\[%L10n\.msg\('(.*?)'\)%\]/g;
我为你创建了这个正则表达式
(?:\[%L10n.msg\(')([A-Za-zť ]+)
它符合您的需要,但如果是斯洛伐克字符,您可能需要调整一下? 结果在group1
你可以看这里
解决匹配问题的最简单方法是使正则表达式的 .*
部分成为非贪婪的,方法是在末尾添加 ?
。
您的编码问题更难解决,因为它取决于数据文件的编码以及您将数据读入文件的方式。所以我们需要更多信息。
这个版本适合我:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $content_from_file = <<END_OF_TXT;
<div class="detail-trash">
<span class="blog-article-social-net social-net-fb">
<svg class="svg-icon-facebook">
<use xlink:href="[%domain.url_media%]/images/svg-sprite.svg#svg-icon-facebook"></use>
</svg>
[%L10n.msg('Zdielať')%]
</span>
<span class="previews-counter">Počet hodnotení: [%product.rating_votes%]</span>
<a href="#" title="[%L10n.msg('Zobraziť recenzie')%]" class="previews-btn js-previews-btn">[%L10n.msg('Zobraziť recenzie')%]</a>
</div>
END_OF_TXT
my (@L10n) = $content_from_file =~ /\[\%L10n\.msg\('(.*?)'\)\%\]/g;
say Dumper @L10n;
输出:
$VAR1 = 'Zdielať';
$VAR2 = 'Zobraziť recenzie';
$VAR3 = 'Zobraziť recenzie';