How can I match strings that don't match a particular pattern in Perl?

前端 未结 6 1646
别跟我提以往
别跟我提以往 2021-02-06 00:25

I know that it is easy to match anything except a given character using a regular expression.

$text = \"ab ac ad\";
$text =~ s/[^c]*//g; # Match anything, except         


        
6条回答
  •  自闭症患者
    2021-02-06 00:42

    $text =~ s/[^c]*//g; // Match anything, except c.
    

    @ssn, A couple of comments about your question:

    1. "//" is not a comment in Perl. Only "#" is.
    2. "[^c]*" - there is no need for the "*" there. "[^c]" means the character class composed of all characters except the letter "c". Then you use the /g modifier, meaning all such occurrences in the text will be replaced (in your example, with nothing). The "zero or more" ("*") modifier is therefore redundant.

    How would I "match anything, except 'ac'" ? Tried [^(ac)] and [^"ac"] without success.

    Please read the documentation on character classes(See "perldoc perlre" on your command line, or online at http://perldoc.perl.org/perlre.html ) - you'll see it states that for the list of characters within the square brackets the RE will "match any character from the list". Meaning order is not relevant and there are no "strings", only a list of characters. "()" and double quotes also have no special meaning inside the square brackets.

    Now I'm not exactly sure why you're talking about matching but then giving an example of substitution. But to see if a string does not match the sub-string "ac" you just need to negate the match:

    use strict; use warnings;
    my $text = "ab ac ad";
    if ($text !~ m/ac/) {
       print "Yey the text doesn't match 'ac'!\n"; # this shouldn't be printed
    }
    

    Say you have a string of text within which are embedded multiple occurrences of a substring. If you just want the text surrounding the sub-string, just remove all occurrences of the sub-string:

    $text =~ s/ac//g;
    

    If you want the reverse - to remove all text except for all occurrences of the sub-string, I would suggest something like:

    use strict; use warnings;
    my $text = "ab ac ad ac ae";
    my $sub_str = "ac";
    my @captured = $text =~ m/($sub_str)/g;
    my $num = scalar @captured;
    print (($sub_str x $num) . "\n");
    

    This basically counts the number of times the sub-string appears in the text and prints the sub-string that number of times using the "x" operator. Not very elegant, I'm sure a Perl-guru could come up with something better.


    @ennuikiller:

    my $text = "ab ac ad";
    $text !~ s/(ac)//g; # Match anything, except ac.
    

    This is incorrect, since it generates a warning ("Useless use of negative pattern binding (!~) in void context") under "use warnings" and doesn't do anything except remove all substrings "ac" from the text, which could be more simply written as I wrote above with:

    $text =~ s/ac//g;
    

提交回复
热议问题