【问题标题】:How can I remove all characters from string starting at first non-alpha character?如何从第一个非字母字符开始的字符串中删除所有字符?
【发布时间】:2009-02-03 16:52:44
【问题描述】:

如果不是在某些情况下,这会容易得多。

样本数据:

KENP989SD
KENP913E
KENPX189R
KENP913

我可以使用什么正则表达式从字符串中删除从第一个非字母字符开始的所有字符?基本上,我想找到第一个非字母字符,然后将所有内容都删除,而不管字符类型如何。

应用正则表达式后,这些数据应该是:

KENP
KENP
KENPX
KENP

【问题讨论】:

  • 所以基本上,你希望它第一个非阿尔法。对于“KENPX189R”,“最后一个 alpha”之后将是 '',因为“最后一个 alpha”(就行是 'R'。
  • 是的,你的权利......我会细化标题/描述

标签: regex perl string parsing


【解决方案1】:

$s =~ s/[^a-zA-Z].*$//;

从字面上看,找到第一个非 alpha 字符并从它开始切掉所有内容。

【讨论】:

  • 在他的示例中,他删除了第一个非 alpha 之后的所有字符,而不是最后的所有非 alpha。
  • 什么可能是必要的警告:什么被视为字母字符?根据您的输入,这可能超过 /[a-zA-Z]/ ...
  • 尾随 $ 无用,因为 .* 是贪婪的。
【解决方案2】:

您以两种方式表达了请求:

  1. 去掉这些字符串前面的所有 alpha 字符
  2. 找到最后一个 alpha 字符,然后将所有内容切掉

虽然给定示例字符串的结果是相同的,但我发现对正则表达式更加小心是值得的。所以,我把上面的第一项作为真正的需求,写成:

$str =~ s/^([a-z]*)[^a-z].*/$1/i;

我认为的优势是意外字符串(如“7KENP989SD”)在替换后应该导致空字符串,而不是像“7KENP”这样的意外字符串。当然,也许这就是你想要的……

【讨论】:

  • 它的措辞有两种方式,但同样的事情......通过“去掉所有的 alpha 字符”,我的意思是将它们分开并将它们存储到另一个变量中
【解决方案3】:
s/([A-Za-z]*).*/$1/

... 会起作用的。这不一定是最好的方法,但它是一般情况下的替换。

仅当您只需要字母字符时才有效

【讨论】:

    【解决方案4】:

    s/\P{Alpha}.*// 很适合我:

    perl -pe 's/\P{Alpha}.*//' <<EOF
    KENP989SD
    KENP913E
    KENPX189R
    KENP913
    EOF
    

    【讨论】:

      【解决方案5】:

      也许是这样的:

      s/(?<=^[A-Z]+).*//
      

      使用look-behind将起始字母后的所有内容替换为空白。


      如有必要,添加不区分大小写的 i 标志:

      s/(?<=^[A-Z]+).*//i
      

      【讨论】:

        【解决方案6】:

        注意:我认为 Igor 的效率更高。

        $str =~ s{^([A-Z]+).*}{$1};
        

        为不区分大小写的匹配添加“i”标志

        $str =~ s{^([A-Z]+).*}{$1}i;
        

        【讨论】:

        • 其实我做了一个快速测试,1,000,000 次迭代 4 个字符串,我的平均是 15 秒,Igor 是 3 :)
        【解决方案7】:

        这是我的尝试。

        /^([A-Za-z]).$/


        编辑我比我更喜欢 Igor 的方法..


        代码:

        #!/usr/bin/perl
        #
        # http://stackoverflow.com/questions/507941/perl-regex-remove-all-characters-from-string-after-last-alpha-character
        #
        use strict;
        use warnings;
        for my $string (<DATA>){
            $string =~ /^([A-Za-z]*).*$/;
            print "$1\n";
        }
        __DATA__
        KENP989SD
        KENP913E
        KENPX189R
        KENP913
        

        【讨论】:

          【解决方案8】:

          如果你不需要自己修改输入行,我用这个多一点:

          my ( $alpha_prefix ) = ( $input_line =~ /^(\p{IsAlpha}*)/ );
          

          在绝大多数情况下,我的大部分变量都是词法,所以还有一些变量不会伤害到我,也可以防止我可能歪曲输入。另外,它通过了taint

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-04-26
            • 1970-01-01
            • 2018-12-02
            • 2013-04-30
            • 2015-02-26
            • 1970-01-01
            • 2013-01-19
            相关资源
            最近更新 更多