代码之家  ›  专栏  ›  技术社区  ›  alvas

只将第一个字母大写

  •  1
  • alvas  · 技术社区  · 6 年前

    在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{$_};
            }
        }
    

    但它似乎要取代 &uppercase(\$WORD[$i]) &uppercase(\$_) 具有 ucfirst(\$WORD[$i]) ucfirst(\$_) 是不同的。

    3 回复  |  直到 6 年前
        1
  •  2
  •   ikegami Gilles Quénot    6 年前

    ucfirst 不等于以下值:

    sub uppercase {     
        my ($W) = @_;       
        $$W = uc(substr($$W,0,1)).substr($$W,1);        
    }
    

    UC1 主要是 〔1〕 相当于以下:

    sub ucfirst {     
        my ($W) = @_;       
        return uc(substr($W,0,1)).substr($W,1);        
    }
    

    如果你想重写 uppercase 依据 UC1 ,如下所示:

    sub uppercase {     
        my ($W) = @_;
        $$W = ucfirst($$W);    
    }
    
    uppercase(\$string);
    

    这意味着如果你想消除 大写字母 完全,你会替换

    uppercase(\$string);
    

    具有

    $string = ucfirst($string);     # Correct
    

    你尝试使用

    ucfirst(\$string);              # Wrong
    

    1. UC1 实际上在处理更深奥的字符方面做得更好,比如u+01f3拉丁文小写字母dz(“”)。
        2
  •  2
  •   aschepler    6 年前

    由于某些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");
    

    打印“不同”。

        3
  •  2
  •   Dave Cross    6 年前

    在Perl中,有ucfirst函数。

    这是否等同于:

    让我们看看……

    $ 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
    

    所以,是的,看起来它们是一样的(至少对于我有限的一组测试来说)。

    我使用的是Perl5.26.1,但我认为这对于所有Perl版本都可以,至少可以恢复到5.10。

    更新:

    我对你的代码做了一个无声的编辑,但我忘了提。您的代码最初用于对标量的引用,但我将其更改为对标量的引用。( $W 而不是 $$W )我认为这是一个无害的替代品。

    但现在你给我们看了 your change in context 我能看到发生了什么。

    你曾经拥有:

    &uppercase(\$WORD[$i])
    

    你把它改为:

    ucfirst(\$WORD[$i])
    

    这不起作用 ucfirst() 不更改其参数;它返回已更改的值。所以你实际上想要:

    $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;
      }
    }