【问题标题】:Perl, split a string before the first alphabetic characterPerl,在第一个字母字符之前拆分字符串
【发布时间】:2013-11-27 03:33:01
【问题描述】:

在 Perl 中,我希望在第一个字母之前分割一个字符串(不管它的位置如何)。我不希望分隔符消失。

例如,如果字符串是12345AB2345,我想拆分第一个字母A,我需要两个字符串:12345AB2345

我尝试使用如下代码,但它没有正确拆分。

$string = "12345A2345"
$substring = substr($string, 0, index($string, /[a-zA-Z]/);
$remainder = substr($string, index($string, /[a-zA-Z]/);

字符串中可以有多个字母。

我认为我的问题涉及 substr 不能使用正则表达式的事实。

【问题讨论】:

  • 字符串是否只包含 ASCII 字母和数字?
  • 是的。除了数字和英文字母,我认为我不需要其他任何东西。

标签: string perl substr


【解决方案1】:

还有另一种方式:

my $string = "12345A2345";
my ($substring, $remainder) = split /(?=[a-z])/i, $string, 2;

【讨论】:

    【解决方案2】:

    我可能会在这里使用split,因为毕竟这就是你正在做的事情。下面我给你3种方式的选择:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use Test::More;
    
    while( <DATA>)
      { chomp;
        my( $string, $expected_substring, $expected_remainder)= split /\s+/;
    
        { # method 1: split on letter, captured letter is added to the remainder
          #           the 3rd arg to split is the LIMIT (see perldoc -f split)
          my( $substring, $letter, $remainder)= split /([a-zA-Z])/, $string, 2;
          $remainder= $letter . $remainder if $letter;
    
          is( $substring, $expected_substring, "method 1, substring, s: '$string'");
          is( $remainder, $expected_remainder, "method 1, remainder, s: '$string'");
        }
    
        { # method 2: add space before letter, split on space 
          my $string_copy= $string;          # or $string would be modified
          $string_copy=~ s/([a-zA-Z])/ $1/;
          my( $substring, $remainder)= split / /, $string_copy, 2;
    
          is( $substring, $expected_substring, "method 2, substring, s: '$string'");
          is( $remainder, $expected_remainder, "method 2, remainder, s: '$string'");
        }
    
        { # method 3: method 2 shortened using s//r (perl 5.14 and above)
          my( $substring, $remainder)= split / /,  $string=~ s/([a-zA-Z])/ $1/r, 2;
    
          is( $substring, $expected_substring, "method 3, substring, s: '$string'");
          is( $remainder, $expected_remainder, "method 3, remainder, s: '$string'");
        }
      }
    
    done_testing();
    
    # test data, string, substring and remainder are on one line, space separated
    __DATA__
    12345A678  12345 A678  
    12345AB678 12345 AB678
    12345A67B8 12345 A67B8
    12345678   12345678
    

    【讨论】:

      【解决方案3】:

      试试,

      my ($substring,$remainder) = $string =~ /^([^a-zA-Z]*)([a-zA-Z].*)$/ ;
      

      如果你需要处理没有字母的情况,那么你可以这样做:

      my ($substring,$remainder) = $string =~ /^([^a-zA-Z]*)([a-zA-Z].*)?$/ ;
      

      【讨论】:

      • 我为缺乏明确性表示歉意。我已经编辑了这个问题以更好地解释自己。我认为该代码仅在字符串中有一个字母时才有效??? (也就是说从第二个字母开始的所有东西都会丢失?)
      • [a-zA-Z] 匹配一个字母。然后.* 匹配该行的其余部分。
      • 这很好,但是如果字符串中根本没有字母,那么这个模式将无法匹配任何内容。这样的事情可能更接近:my ($substring, $remainder) = $string =~ /^([^[:alpha:]]*)(.*)$/;
      • 要求匹配“第一个字母”的问题。如果您需要允许没有字母,您可以使第二个 () 有条件。
      • @J.A.如果字符串中有多个字母,会发生什么?是否也应该在这些字母上拆分?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-29
      • 2017-06-02
      • 2021-03-10
      • 1970-01-01
      • 2015-08-15
      • 1970-01-01
      相关资源
      最近更新 更多