Want metachars escaped so they are not interpreted in regexp

Discussion in 'Perl Misc' started by Markus Dehmann, Jan 5, 2006.

  1. I have a pattern that I want to match against some text. The pattern may
    contain some chars that happen to be metachars, but I don't want them to
    be interpreted as metachars:

    my $pattern = 'Hello...?';
    $_ = 'Oh Hello x';
    if(m/$pattern/){
    print "Oh no, it matches!\n"; # it matches indeed!
    }

    How do I prepare the $pattern properly before using it in the regexp?

    I used something like this:

    sub encode {
    my $s = $_[0];
    $s =~ s/(.)/sprintf "\\x%x",ord($1)/ge;
    return $s;
    }

    to encode the pattern before using it in the regexp, but I think it's
    inefficient and inelegant...?

    Does anyone have a better escape function?

    Thanks!
    Markus

    P.S.: I'm sorry if this is a FAQ (it should be!), but I googled and
    didn't find anything.
    Markus Dehmann, Jan 5, 2006
    #1
    1. Advertising

  2. Markus Dehmann

    Anno Siegel Guest

    Markus Dehmann <> wrote in comp.lang.perl.misc:
    > I have a pattern that I want to match against some text. The pattern may
    > contain some chars that happen to be metachars, but I don't want them to
    > be interpreted as metachars:


    perldoc -f quotemeta

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Jan 5, 2006
    #2
    1. Advertising

  3. Markus Dehmann

    robic0 Guest

    On Thu, 05 Jan 2006 01:13:48 -0500, Markus Dehmann <> wrote:

    >I have a pattern that I want to match against some text. The pattern may
    >contain some chars that happen to be metachars, but I don't want them to
    >be interpreted as metachars:
    >
    >my $pattern = 'Hello...?';
    >$_ = 'Oh Hello x';
    >if(m/$pattern/){
    > print "Oh no, it matches!\n"; # it matches indeed!
    >}
    >
    >How do I prepare the $pattern properly before using it in the regexp?
    >
    >I used something like this:
    >
    >sub encode {
    > my $s = $_[0];
    > $s =~ s/(.)/sprintf "\\x%x",ord($1)/ge;
    > return $s;
    >}
    >
    >to encode the pattern before using it in the regexp, but I think it's
    >inefficient and inelegant...?
    >
    >Does anyone have a better escape function?
    >
    >Thanks!
    >Markus
    >
    >P.S.: I'm sorry if this is a FAQ (it should be!), but I googled and
    >didn't find anything.


    Be carefull how you use strings mixed with escape characters when they
    are called out as declared constants in your program. For the most part
    you don't want to fight the expression parser of your interpreter.
    After digesting your constant string, I call it "in-solution" like in
    Chemistry. When "in-solution" it is safe from mangling of editors and
    parsers. Typically, the string you want to match against would be data
    read in by your program from a file. In that case it is always "in-solution".
    -robic0-


    use strict;
    use warnings;

    my ($pat_convert);

    $pat_convert = convertPatternMeta ( 'Hello...?' );
    showMatchResult ($pat_convert, 'Hello...? this is a big string x');
    showMatchResult ($pat_convert, 'Oh Hello x');

    $pat_convert = convertPatternMeta ( '*?+' );
    showMatchResult ($pat_convert, 'Hello...? this (*?+) is a big string x');
    showMatchResult ($pat_convert, '*?+ and so is this');

    ## ------------------------------------
    ## Helpers
    ##
    sub convertPatternMeta
    {
    my ($pattern) = shift;
    my @regx_esc_codes =
    (
    "\\", '/', '(', ')', '[', ']', '?', '|',
    '+', '.', '*', '$', '^', '{', '}', '@'
    );
    foreach my $tc (@regx_esc_codes) {
    # code template for regex
    my $xxx = "\$pattern =~ s/\\$tc/\\\\\\$tc/g;";
    eval $xxx;
    if ($@) {
    # the compiler will show the escape char, add
    # it char to @regx_esc_codes
    $@ =~ s/^[\s]+//s; $@ =~ s/[\s]+$//s;
    die "$@";
    }
    }
    return $pattern;
    }
    ##
    sub showMatchResult
    {
    my ($pattern, $string) = @_;
    my $result_txt = '';
    my ($result) = $string =~ /$pattern/;
    if ($result) { $result_txt = 'DOES match'}
    else { $result_txt = 'Does NOT match' }
    print "\nString: $string\n$result_txt\nPattern: $pattern\n";
    }
    __DATA__

    String: Hello...? this is a big string x
    DOES match
    Pattern: Hello\.\.\.\?

    String: Oh Hello x
    Does NOT match
    Pattern: Hello\.\.\.\?

    String: Hello...? this (*?+) is a big string x
    DOES match
    Pattern: \*\?\+

    String: *?+ and so is this
    DOES match
    Pattern: \*\?\+
    robic0, Jan 6, 2006
    #3
  4. Markus Dehmann

    robic0 Guest

    On 5 Jan 2006 08:27:58 GMT, -berlin.de (Anno Siegel) wrote:

    >Markus Dehmann <> wrote in comp.lang.perl.misc:
    >> I have a pattern that I want to match against some text. The pattern may
    >> contain some chars that happen to be metachars, but I don't want them to
    >> be interpreted as metachars:

    >
    >perldoc -f quotemeta
    >
    >Anno


    Your an absurd example of a lump of lard
    -robic0-
    robic0, Jan 6, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Asfand Yar Qazi
    Replies:
    4
    Views:
    395
    Asfand Yar Qazi
    Nov 12, 2004
  2. Fernando Rodriguez
    Replies:
    5
    Views:
    397
    Roel Mathys
    Nov 20, 2003
  3. Martin M.
    Replies:
    4
    Views:
    340
    Simon Brunning
    Dec 15, 2005
  4. Dave Rudolf
    Replies:
    1
    Views:
    299
    Kai-Uwe Bux
    May 17, 2006
  5. Joao Silva
    Replies:
    16
    Views:
    355
    7stud --
    Aug 21, 2009
Loading...

Share This Page