#!/usr/bin/perl
@lines = `perldoc -u -f atan2`;
foreach (@lines) {
s/\w<([^>]+)>/\U$1/g;
print;
}
表达式将如何s/\w<([^>]+)>/\U$1/g;
工作?
#!/usr/bin/perl
@lines = `perldoc -u -f atan2`;
foreach (@lines) {
s/\w<([^>]+)>/\U$1/g;
print;
}
表达式将如何s/\w<([^>]+)>/\U$1/g;
工作?
替换是这样做的:
s/
\w< # look for a single alphanumeric character followed by <
([^>]+) # capture one or more characters that are not <
> # followed by a >
/ ### replace with
\U # change following text to uppercase
$1 # the captured string from above
/gx # /g means do this as many times as possible per line
我添加了/x
修饰符以便能够可视化正则表达式。字符类[^>]
被否定,如^
之后的字符表示[
,表示“除”之外的任何字符>
。
例如,在 perldoc 命令的输出中
X<atan2> X<arctangent> X<tan> X<tangent>
改为
ATAN2 ARCTANGENT TAN TANGENT
这是弄清楚它在做什么的另一种选择。使用来自 CPAN的模块YAPE::Regex::Explain 。
以这种方式使用它(这只是搜索和替换的匹配部分):
use strict;
use YAPE::Regex::Explain;
print YAPE::Regex::Explain->new(qr/\w<([^>]+)>/)->explain();
将给出这个输出:
The regular expression:
(?-imsx:\w<([^>]+)>)
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
\w word characters (a-z, A-Z, 0-9, _)
----------------------------------------------------------------------
< '<'
----------------------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------------------
[^>]+ any character except: '>' (1 or more
times (matching the most amount
possible))
----------------------------------------------------------------------
) end of \1
----------------------------------------------------------------------
> '>'
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
表达式的替换部分说明早先在“group and capture to \1”和“end of \1”之间进行的匹配应转换为大写。
perl 循环如下所示:
foreach $item (@array)
{
# Code in here. ($item takes a new value from array each iteration)
}
但是 perl 允许您几乎在任何地方都省略变量。
当您这样做时,将$_
使用特殊变量。
所以在你的情况下:
foreach (@lines)
{
}
与以下内容完全相同:
foreach $_ (@lines)
{
}
现在在正文中添加以下代码:
s/\w<([^>]+)>/\U$1/g;
有同样的事情发生。您实际上正在处理一个变量。而当你不指定变量时,perl 默认为$_
.
因此它相当于:
$_ =~ s/\w<([^>]+)>/\U$1/g;
将两者结合起来:
foreach (@lines) {
s/\w<([^>]+)>/\U$1/g;
print;
}
也等价:
foreach $item (@lines)
{
$item =~ s/\w<([^>]+)>/\U$1/g;
print $item;
}
我$item
只是为了可读性。在内部它意味着$_
.
许多 perl 代码使用这种类型的快捷方式。就我个人而言,我认为它使阅读变得更加困难(即使对于有经验的 perl 程序员也是如此(这是 perl 以不可读而闻名的原因之一))。因此,我总是尝试明确变量的使用(但这(我的用法)不是典型的 perl 用法)。