1

I want to inspect a perl array whether it provides a certain value.

How can I check if a Perl array contains a particular value? tells me that I could use grep( /^$value$/, @array ) in order to check whether $value is already contained in @array.

This works as long as $value doesn't have special characters. Unfortunately, my array elements are paths of a visual studio project which look like $(MY_USER_MACRO)/includes/myfile.h For these elements, grep( /^$value$/, @array ) always returns false although there are numerous of such entries already present in @array.

I assume that the problem occurs because $value has the $ character in it and therefore somehow breaks the grep execution.

Is there a way to tell grep to take the given string literally? If not: how could I solve my problem then?

Community
  • 1
  • 1
eckes
  • 64,417
  • 29
  • 168
  • 201

3 Answers3

8

Quote your regex:

grep( /^\Q$value\E$/, @array )

You could also do, as your're testing equality:

grep( $_ eq $value, @array )
ikegami
  • 367,544
  • 15
  • 269
  • 518
Toto
  • 89,455
  • 62
  • 89
  • 125
  • Using `\Q` tells the `//` operator, not `grep` to treat `$value` as a regular expression (or, more precisely, to convert it to a regular expression that matches `$value` literally). But the first argument to `grep` can be any arbitrary block or expression, not just a regexp match. – Keith Thompson Apr 15 '14 at 14:34
  • Using `grep { $_ eq $value} @array` and I'm happy. Thx. – eckes Apr 15 '14 at 14:36
  • 1
    @KeithThompson: I cannot read anything that helps me from your comment. What would you do? And http://perldoc.perl.org/functions/grep.html is one of the worst docs I've ever seen... – eckes Apr 15 '14 at 14:38
  • @eckes: What exactly confuses you about my comment? (If that's one of the worst documents you've ever seen, you've been incredibly lucky.) – Keith Thompson Apr 15 '14 at 14:44
  • 4
    Note that those two aren't quite equivalent. The first will match `$value` and `$value\n`, while the second will only match `$value`. The second would be equivalent to `/^\Q$value\E\z/` – ikegami Apr 15 '14 at 15:11
0

grep { index($_, $value) >= 0} @array;

perldoc -f index

index STR,SUBSTR,POSITION
index STR,SUBSTR
The index function searches for one string within another, but without the wildcard-like behavior of a full regular-expression pattern match. It returns the position of the first occurrence of SUBSTR in STR at or after POSITION. If POSITION is omitted, starts searching from the beginning of the string. POSITION before the beginning of the string or after its end is treated as if it were the beginning or the end, respectively. POSITION and the return value are based at 0 (or whatever you've set the $[ variable to--but don't do that). If the substring is not found, "index" returns one less than the base, ordinarily "-1".

MolbOrg
  • 105
  • 1
  • 5
0

Another solution to those above, is that if you only care about the presence of at least one matching value, and you don't care how many of them there are, you could use the any function from List::Util.

use List::Util 'any';

if( any { $_ eq $value } @array ) {
  ...
}
LeoNerd
  • 8,344
  • 1
  • 29
  • 36