通过仅大写第一个字母来将单词大写
Capitalizing words by uppercasing only the first letter
在 Perl 中,有 ucfirst 函数。
这是否等同于:
sub uppercase {
my ($W) = @_;
$$W = uc(substr($$W,0,1)).substr($$W,1);
}
跨 Perl 版本是否重要?
将问题背景化,https://github.com/moses-smt/mosesdecoder/pull/206/files#diff-876e51db2a1ab71c1ae736182d1e5e04R63,
以前,uppercase
的用法是这样的:
sub process {
my $line = $_[0];
chomp($line);
$line =~ s/^\s+//;
$line =~ s/\s+$//;
my @WORD = split(/\s+/,$line);
# uppercase at sentence start
my $sentence_start = 1;
for(my $i=0;$i<scalar(@WORD);$i++) {
&uppercase($WORD[$i]) if $sentence_start;
if (defined($SENTENCE_END{ $WORD[$i] })) { $sentence_start = 1; }
elsif (!defined($DELAYED_SENTENCE_START{$WORD[$i] })) { $sentence_start = 0; }
}
# uppercase headlines {
if (defined($SRC) && $HEADLINE[$sentence]) {
foreach (@WORD) {
&uppercase($_) unless $ALWAYS_LOWER{$_};
}
}
但是用ucfirst($WORD[$i])
和ucfirst($_)
替换&uppercase($WORD[$i])
和&uppercase($_)
似乎是不同的。
In Perl, there's the ucfirst function.
Is it this the equivalent to this:
让我们找出答案...
$ cat testuc
use strict;
use warnings;
use Test::More;
sub uppercase {
my ($w) = @_;
return uc(substr($w, 0, 1)) . substr($w, 1);
}
my @tests = qw[foobar Foobar FOOBar fOObar fOObAR FOOBAR];
for (@tests) {
is(ucfirst($_), uppercase($_), "correct for $_");
}
done_testing;
$ prove -v testuc
testuc ..
ok 1 - correct for foobar
ok 2 - correct for Foobar
ok 3 - correct for FOOBar
ok 4 - correct for fOObar
ok 5 - correct for fOObAR
ok 6 - correct for FOOBAR
1..6
ok
All tests successful.
Files=1, Tests=6, 0 wallclock secs ( 0.04 usr 0.03 sys + 0.03 cusr 0.04 csys = 0.14 CPU)
Result: PASS
所以,是的,看起来它们是同一回事(至少对于我相当有限的一组测试而言)。
我使用的是 Perl 5.26.1 - 但我认为这对于至少回到 5.10 的所有 Perl 版本都可以正常工作。
更新:
我对您的代码进行了静默编辑,但我忘了提及。您的代码最初处理对标量的引用,但我将其更改为处理标量($W
而不是 $$W
)。我认为这将是一种无害的替代品。
但现在你向我们展示了 your change in context,我可以看到发生了什么。
你有:
&uppercase($WORD[$i])
然后您将其更改为:
ucfirst($WORD[$i])
这不起作用,因为 ucfirst()
没有改变它的参数;它 returns 更改后的值。所以你实际上想要:
$WORD[$i] = ucfirst($WORD[$i]);
这将按预期工作(模数其他答案中提到的 Unicode 字符问题。
如果你摆脱 C 风格的 for
循环,你的整个循环可以得到简化。
for my $w (@WORD) {
$w = ucfirst($w) if $sentence_start;
if (defined $SENTENCE_END{ $w }) {
$sentence_start = 1;
} elsif (!defined $DELAYED_SENTENCE_START{ $w }) {
$sentence_start = 0;
}
}
ucfirst
不等同于以下内容:
sub uppercase {
my ($W) = @_;
$$W = uc(substr($$W,0,1)).substr($$W,1);
}
ucfirst
主要是 [1] 等同于以下内容:
sub ucfirst {
my ($W) = @_;
return uc(substr($W,0,1)).substr($W,1);
}
如果你想用 ucfirst
重写 uppercase
,它看起来像这样:
sub uppercase {
my ($W) = @_;
$$W = ucfirst($$W);
}
uppercase($string);
这意味着如果你想完全消除 uppercase
,你将替换
uppercase($string);
和
$string = ucfirst($string); # Correct
您尝试使用
ucfirst($string); # Wrong
ucfirst
实际上在处理更深奥的字符方面做得更好,例如 U+01F3 拉丁小写字母 DZ(“dz”)。
由于一些 Unicode 细节,函数不等价,尤其是处理 digraphs。
例如,匈牙利语使用二合字母 "DZ",它被视为字母表中的单个字母,因此可以选择使用 Unicode 代码点表示:
U+01F1
: DZ
U+01F2
:Dz
U+01F3
: dz
所以
my $text1 = "\x{1f3}won";
my $text2 = $text1;
$text1 = ucfirst($text1);
uppercase($text2);
print($text1 eq $text2 ? "same\n" : "different\n");
打印 "different".
在 Perl 中,有 ucfirst 函数。
这是否等同于:
sub uppercase {
my ($W) = @_;
$$W = uc(substr($$W,0,1)).substr($$W,1);
}
跨 Perl 版本是否重要?
将问题背景化,https://github.com/moses-smt/mosesdecoder/pull/206/files#diff-876e51db2a1ab71c1ae736182d1e5e04R63,
以前,uppercase
的用法是这样的:
sub process {
my $line = $_[0];
chomp($line);
$line =~ s/^\s+//;
$line =~ s/\s+$//;
my @WORD = split(/\s+/,$line);
# uppercase at sentence start
my $sentence_start = 1;
for(my $i=0;$i<scalar(@WORD);$i++) {
&uppercase($WORD[$i]) if $sentence_start;
if (defined($SENTENCE_END{ $WORD[$i] })) { $sentence_start = 1; }
elsif (!defined($DELAYED_SENTENCE_START{$WORD[$i] })) { $sentence_start = 0; }
}
# uppercase headlines {
if (defined($SRC) && $HEADLINE[$sentence]) {
foreach (@WORD) {
&uppercase($_) unless $ALWAYS_LOWER{$_};
}
}
但是用ucfirst($WORD[$i])
和ucfirst($_)
替换&uppercase($WORD[$i])
和&uppercase($_)
似乎是不同的。
In Perl, there's the ucfirst function.
Is it this the equivalent to this:
让我们找出答案...
$ cat testuc
use strict;
use warnings;
use Test::More;
sub uppercase {
my ($w) = @_;
return uc(substr($w, 0, 1)) . substr($w, 1);
}
my @tests = qw[foobar Foobar FOOBar fOObar fOObAR FOOBAR];
for (@tests) {
is(ucfirst($_), uppercase($_), "correct for $_");
}
done_testing;
$ prove -v testuc
testuc ..
ok 1 - correct for foobar
ok 2 - correct for Foobar
ok 3 - correct for FOOBar
ok 4 - correct for fOObar
ok 5 - correct for fOObAR
ok 6 - correct for FOOBAR
1..6
ok
All tests successful.
Files=1, Tests=6, 0 wallclock secs ( 0.04 usr 0.03 sys + 0.03 cusr 0.04 csys = 0.14 CPU)
Result: PASS
所以,是的,看起来它们是同一回事(至少对于我相当有限的一组测试而言)。
我使用的是 Perl 5.26.1 - 但我认为这对于至少回到 5.10 的所有 Perl 版本都可以正常工作。
更新:
我对您的代码进行了静默编辑,但我忘了提及。您的代码最初处理对标量的引用,但我将其更改为处理标量($W
而不是 $$W
)。我认为这将是一种无害的替代品。
但现在你向我们展示了 your change in context,我可以看到发生了什么。
你有:
&uppercase($WORD[$i])
然后您将其更改为:
ucfirst($WORD[$i])
这不起作用,因为 ucfirst()
没有改变它的参数;它 returns 更改后的值。所以你实际上想要:
$WORD[$i] = ucfirst($WORD[$i]);
这将按预期工作(模数其他答案中提到的 Unicode 字符问题。
如果你摆脱 C 风格的 for
循环,你的整个循环可以得到简化。
for my $w (@WORD) {
$w = ucfirst($w) if $sentence_start;
if (defined $SENTENCE_END{ $w }) {
$sentence_start = 1;
} elsif (!defined $DELAYED_SENTENCE_START{ $w }) {
$sentence_start = 0;
}
}
ucfirst
不等同于以下内容:
sub uppercase {
my ($W) = @_;
$$W = uc(substr($$W,0,1)).substr($$W,1);
}
ucfirst
主要是 [1] 等同于以下内容:
sub ucfirst {
my ($W) = @_;
return uc(substr($W,0,1)).substr($W,1);
}
如果你想用 ucfirst
重写 uppercase
,它看起来像这样:
sub uppercase {
my ($W) = @_;
$$W = ucfirst($$W);
}
uppercase($string);
这意味着如果你想完全消除 uppercase
,你将替换
uppercase($string);
和
$string = ucfirst($string); # Correct
您尝试使用
ucfirst($string); # Wrong
ucfirst
实际上在处理更深奥的字符方面做得更好,例如 U+01F3 拉丁小写字母 DZ(“dz”)。
由于一些 Unicode 细节,函数不等价,尤其是处理 digraphs。
例如,匈牙利语使用二合字母 "DZ",它被视为字母表中的单个字母,因此可以选择使用 Unicode 代码点表示:
U+01F1
: DZU+01F2
:DzU+01F3
: dz
所以
my $text1 = "\x{1f3}won";
my $text2 = $text1;
$text1 = ucfirst($text1);
uppercase($text2);
print($text1 eq $text2 ? "same\n" : "different\n");
打印 "different".