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

Dear Monks

I have a 6 character string (alphanumeric) and i want to check the particular char at particular position to buld my condition. for example: in string XXXXpX, i care only about char "p" at 5th position and if it matches then my condition is met.

i used following regex in my program:

my $strTest = "ABCDpF"; if (grep {m/.?.?.?.?p.?/i} $strTest) { print "String matched the Pattern"; }

it works in most of my test cases. but i used a string "tp7avs" where i assume it should not match but it does. Could anyone help?

-KAKA-

Replies are listed 'Best First'.
Re: Perl RegEx doubt
by choroba (Cardinal) on Jun 07, 2016 at 12:47 UTC
    TIMTOWTDI: You can avoid regex completely. Use substr:
    if ('p' eq substr $strTest, 4, 1) {

    or index

    if (4 == index $strTest, 'p', 4) {

    or, a bitmask:

    if (($strTest & "\0\0\0\0\xff\0") eq "\0\0\0\0p\0") {

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Perl RegEx doubt
by Eily (Monsignor) on Jun 07, 2016 at 12:35 UTC

    Why did you add the '?'s ? They actually mean that the dot may be ignored so of course your regex doesn't do what you want. And even without that, by default regular expressions in perl search for a given pattern anywhere in the string. You need to add the token ^ or \A (see perlre and perlreref) to only match from the beginning of the line or string.

    Anyway, in this case regular expressions are probably not the right tool, substr seems more appropriate and easy to use.

    BTW, grep selects items in a list, $strTest is a single item, so grep is not needed here.

    Edit: added "probably" in "regular expressions are not the right tool". Although it looks to me that it would be far better for the op to use substr because it does not have all the side effects, hidden rules and modifiers of regexes, I don't know for sure that the fifth char is the only thing that need to be checked.

Re: Perl RegEx doubt
by Corion (Patriarch) on Jun 07, 2016 at 12:35 UTC

    Read perlre and then compare /./ against /.?/. The question marks make the dot optional.

    Most likely, you want something like the following:

    /^....p.$/

    Note the anchors ^ and $ (or alternatively, \A and \z). I've also removed the /i modifier, because you seem want to match a lower-case p only.

Re: Perl RegEx doubt
by hippo (Archbishop) on Jun 07, 2016 at 12:35 UTC

    Omit the question marks as they vary the count.

    #!/usr/bin/env perl use strict; use warnings; use Test::More tests => 2; my $re = qr/....p./; like ('ABCDpF', $re, 'Should match'); unlike ('tp7avs', $re, 'Should not match');
Re: Perl RegEx doubt
by toolic (Bishop) on Jun 07, 2016 at 12:36 UTC
    Get rid of the "?". And I don't think you need grep. This seems more typical:
    if ($strTest =~ m/....p./i)
Re: Perl RegEx doubt
by stevieb (Canon) on Jun 07, 2016 at 12:45 UTC

    This will ensure that the string is exactly six characters, only consists of alpha-num, and matches the 5th char:

    use warnings; use strict; my $str = 'xpy7pG'; my $char = 'p'; if ($str =~ /^\w{4}$char\w$/){ print "matched\n"; }

    update: I lied. The above will also match an underscore (as \w matches [a-zA-Z0-9_]. If you don't want that, you can use this:

    /^[0-9A-Za-z]{4}$char[0-9A-Za-z]$/
      ... [0-9A-Za-z] ...

      There is also  [[:alnum:]] in the POSIX Character Classes (in perlrecharclass) which I tend to prefer as self-documenting.
      Also  \p{IsAlnum} if you've embraced the Dark Side of Unicode.


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