anautismobserver has asked for the wisdom of the Perl Monks concerning the following question:

I want to search an array for an arbitrary sting variable. All the examples I've found use regular expressions. Is there a way to devise a regular expression that includes an arbitrary string variable (unknown in advance)?

For example:

my #string_to_find = 'hidden'; my @array_to_search = ('Foo', 'whathiddenever', 'Bar', '12hidden456');

Replies are listed 'Best First'.
Re: Can a regular expression include an arbitrary string variable?
by davido (Cardinal) on Oct 17, 2019 at 05:01 UTC

    Yes, regular expressions can interpolate variables into them:

    my $string_to_find = 'hidden'; my @array_to_search = qw(Foo whathiddenever Bar 12hidden456); say "Found $_" for grep {m/\Q$string_to_find/} @array_to_search;

    You may also decide you don't need a pattern match, and if you can come to that conclusion you avoid the problem of treating strings as code:

    say "Found $_" for grep {index($_, $string_to_find) > -1} @array_to_se +arch;

    You can observe the rules of how interpolation works in regular expressions by reading perlop and perlre. The index function is also documented at perldoc -f index.

    An advantage of the index approach is that you're not exposing the regular expression mini-language and engine to arbitrary strings, which could contain code. It's also lighter-weight, not invoking the engine.


    Dave

Re: Can a regular expression include an arbitrary string variable?
by AnomalousMonk (Archbishop) on Oct 17, 2019 at 02:47 UTC

    I'm not quite sure what you mean by "arbitrary string variable" and "unknown in advance", but maybe something like:

    c:\@Work\Perl\monks>perl -wMstrict -le "chomp(my $string_to_find = <STDIN>); ;; my @array_to_search = qw(Foo whathiddenever Bar 12hidden456); ;; for my $s (@array_to_search) { print qq{'$s' has '$string_to_find'} if $s =~ $string_to_find; } " hidden 'whathiddenever' has 'hidden' '12hidden456' has 'hidden'

    Update: In general, strings and, better yet, regex objects created by  qr// (see Regexp Quote-Like Operators in perlop) can be interpolated into and thus used to compose other regex objects:

    c:\@Work\Perl\monks>perl -wMstrict -le "chomp(my $string_to_find = <STDIN>); ;; my @array_to_search = qw(Foo whathi$denever Bar 12hi$den456); ;; my $rx_search = qr{ (?<= \d) \Q$string_to_find\E (?= \d) }xms; ;; for my $s (@array_to_search) { print qq{'$s' has '$string_to_find'} if $s =~ $rx_search; } " hi$den '12hi$den456' has 'hi$den'
    This illustrates both interpolation for composition and metaquoting with  \Q ... \E of an interpolated variable. See Quote and Quote-like Operators in perlop, perlre.


    Give a man a fish:  <%-{-{-{-<

Re: Can a regular expression include an arbitrary string variable?
by trippledubs (Deacon) on Oct 17, 2019 at 02:49 UTC
    #!/usr/bin/env perl my $string_to_find = 'hidden'; my @array_to_search = ('Foo', 'whathiddenever', 'Bar', '12hidden456'); my @matches = grep { /$string_to_find/ } @array_to_search; print "@matches";
Re: Can a regular expression include an arbitrary string variable?
by jcb (Parson) on Oct 17, 2019 at 04:22 UTC

    Simple interpolation will work in the simple case, but if you want regex characters in the string to match literally, you will need either quotemeta or to use the index builtin instead of pattern matching.

Re: Can a regular expression include an arbitrary string variable?
by Anonymous Monk on Oct 17, 2019 at 07:36 UTC

    Hi

    Consider yourself re warned

    $ perl -le"use re 'eval'; no re 'eval'; my $re=shift; 1=~/$re/;" -- "( +??{die666})" Eval-group not allowed at runtime, use re 'eval' in regex m/(??{die666 +})/ at -e line 1.