How can I extract a substring up to the first digit?

后端 未结 4 1132
名媛妹妹
名媛妹妹 2021-01-15 09:01

How can I find the first substring until I find the first digit?

Example:

my $string = \'AAAA_BBBB_12_13_14\' ;

Result expected: \'AAA

相关标签:
4条回答
  • 2021-01-15 09:14
      $str =~ /(\d)/; print $`;
    

    This code print string, which stand before matching

    0 讨论(0)
  • 2021-01-15 09:14
    perl -le '$string=q(AAAA_BBBB_12_13_14);$string=~m{(\D+)} and print $1'
    AAAA_BBBB_
    
    0 讨论(0)
  • 2021-01-15 09:15

    Judging from the tags you want to use a regular expression. So let's build this up.

    • We want to match from the beginning of the string so we anchor with a ^ metacharacter at the beginning
    • We want to match anything but digits so we look at the character classes and find out this is \D
    • We want 1 or more of these so we use the + quantifier which means 1 or more of the previous part of the pattern.

    This gives us the following regular expression:

    ^\D+
    

    Which we can use in code like so:

    my $string = 'AAAA_BBBB_12_13_14';
    $string =~ /^\D+/;
    my $result = $&;
    
    0 讨论(0)
  • 2021-01-15 09:38

    Most people got half of the answer right, but they missed several key points.

    • You can only trust the match variables after a successful match. Don't use them unless you know you had a successful match.

    • The $&, $``, and$'` have well known performance penalties across all regexes in your program.

    • You need to anchor the match to the beginning of the string. Since Perl now has user-settable default match flags, you want to stay away from the ^ beginning of line anchor. The \A beginning of string anchor won't change what it does even with default flags.

    This would work:

    my $substring = $string =~ m/\A(\D+)/ ? $1 : undef;
    

    If you really wanted to use something like $&, use Perl 5.10's per-match version instead. The /p switch provides non-global-perfomance-sucking versions:

    my $substring = $string =~ m/\A\D+/p ? ${^MATCH} : undef;
    

    If you're worried about what might be in \D, you can specify the character class yourself instead of using the shortcut:

    my $substring = $string =~ m/\A[^0-9]+/p ? ${^MATCH} : undef;
    

    I don't particularly like the conditional operator here, so I would probably use the match in list context:

    my( $substring ) = $string =~ m/\A([^0-9]+)/;
    

    If there must be a number in the string (so, you don't match an entire string that has no digits, you can throw in a lookahead, which won't be part of the capture:

    my( $substring ) = $string =~ m/\A([^0-9]+)(?=[0-9])/;
    
    0 讨论(0)
提交回复
热议问题