正则表达式,用于获取Perl中标点符号后的单词的第一个字母

时间:2011-10-17 07:12:41

标签: regex perl

任何正文都可以在Perl中告诉我一个正则表达式,用于获取点,问题或惊叹号后面的单词的第一个字母......

我的程序逐个字符地读取字符串。

要求:

input string : "abcd[.?!]\s*abcd"
output: "Abcd[.?!]\s*Abcd"

我的计划如下:

#!/usr/bin/perl

use strict;

my $str = <STDIN>;
my $len=length($str);
my $ch;

my $i;
for($i=0;$i<=length($str);$i++)
{
$ch = substr($str,$i,1);
print "$ch";
if($ch =~ 's/([.?!]\s*[a-z])/uc($1)/ge')
{
    $i=$i+1;
    $ch = substr($str, $i,1);
    my $ch = uc($ch);
    print "$ch";
}
#elsif($ch eq "?")
#{
#   $i=$i+1;
#   $ch = substr($str, $i,1);
#   my $ch = uc($ch);
#   print "$ch";
#}
#elsif($ch eq "!")
#{
#   $i=$i+1;
#   $ch = substr($str, $i,1);
#   my $ch = uc($ch);
#   print"$ch";
#}
#elsif($ch eq " ")
#{
#   $i=$i+1;
#   $ch = substr($str, $i,1);
#   my $ch = uc($ch);
#   print"$ch";
#}
#else
#{
#print "";
#}
}
print "\n";

4 个答案:

答案 0 :(得分:1)

循环遍历字符串,然后循环遍历匹配,完全是多余的。您的整个程序可以替换为:

perl -pe 's/(^|[.?!]\s*)([a-z])/$1\U\2/g' inputfile >outputfile

我在第一个带括号的表达式中添加了行的开头,虽然你的解释不包括那个(但你的例子确实如此)。

答案 1 :(得分:0)

  

任何正文都可以告诉我perl中的正则表达式,以便在点,问题或惊叹号之后获得该单词的第一个字母......

     

我的程序逐个字符地读取字符串。

     

要求:

     

输入字符串:“abcd [。?!] \ s * abcd”

     

输出:“Abcd [。?!] \ s * Abcd”

您的输出与您的说明不符。在输入中,初始“a”不跟随句点,问号或感叹号,但更改为大写。

您可以而且应该通过一次替换进行此类处理。完全像你说的那样做:

s/[.?!]\K[[:lower:]]/uc($&)/ge

\K丢弃[。?!]匹配的字符,只留下匹配字符串中的小写字母。 $&是匹配的字符串。 e标记表示评估uc($&)

如果您还想将首字母大写:

s/(?:^|[.?!])\K[[:lower:]]/uc($&)/ge

答案 2 :(得分:0)

通常,

$s =~ s/(?<=[.?!]|^)\s*[a-z]/\U$1/g;

$s =~ s/(?<![^.?!])\s*[a-z]/\U$1/g;

$s =~ s/(?:^|[.?!])\s*\K[a-z]/\U$1/g;

但如果你一次只读一个字,

my $after_punc = 1;
while (my $ch = ...) {
    if ($ch =~ /^[.?!]\z/) {
       $after_punc = 1;
    }
    elsif ($ch =~ /^[a-z]\z/) {
       $ch = uc($ch) if $after_punc;
       $after_punc = 0;
    }
    elsif ($ch =~ /^\s\z/) {
       # Ignore whitespace.
    }
    else {
       $after_punc = 0;
    }

    ...
}

答案 3 :(得分:0)

如果你有unicode字符串,你可以使用:

$str =~ s/(\pP|^)(\s*\pL)/$1\U$2/g;