Brandon Coffman
Brandon Coffman

Reputation: 244

Match any substring from the beginning of a word

For example, with a line like previous, I want the pattern to match the lines p, pr, pre, prev, etc., all the way up to previous. I do NOT want it to match lines like prevalent or previse. Is there a pattern to accomplish this aside from the obvious (^(p|pr|pre|prev|...|previous)$)?

Note: I do not need to capture it like in the above pattern, and I'm using Perl's regular expression flavor (in Perl).

Upvotes: 4

Views: 593

Answers (4)

user3408541
user3408541

Reputation: 63

I disagree with the accepted answer. You could get something with substrings to work, but a regex will work well here. Regexs are far superior to substrings in every way for matching text. Regexes are definitely a bit more difficult to write, but this one is about as straight forward as it gets

if( $originalString =~ /^$testString/ )

I think this solution will work in more situations, and is a bit easier to understand and build around than the previous solutions.

#!/usr/bin/perl -w

#determine if $testString is a substring of $originalString
#match from beginning only, not anywhere in string

my $originalString = "previous";
my @testString = qw(p pr pre prev previ previo previou revious previous previousFILLER prevalent previse);
print "\"$originalString\"\n";
for(@testString){
  if($originalString =~ /^$_/){
    print "\"$_\" TRUE\n";
  }else{
    print "\"$_\" FALSE\n";
  }
}

Output looks like this

$ perl matchSubstring.pl
"previous"
"p" TRUE
"pr" TRUE
"pre" TRUE
"prev" TRUE
"previ" TRUE
"previo" TRUE
"previou" TRUE
"revious" FALSE
"previous" TRUE
"previousFILLER" FALSE
"prevalent" FALSE
"previse" FALSE

golfed 79 characters

perl -e '$s=shift;print "$s\n";for(@ARGV){$s=~/^$_/?print "$_ TRUE\n":print "$_ FALSE\n"}' previous p pr pre prev previ previou revious previous previousFILLER prevalent previse

Upvotes: 0

Chankey Pathak
Chankey Pathak

Reputation: 21666

#!/usr/bin/perl
use strict;
use warnings;

my $string = "previous"; 
my @array = split //,$string;

chomp(my $input=<STDIN>); #take the input from the user
my @array2 = split //,$input;

my $i=0;

foreach (@array2){
        if($_ eq $array[$i]){
            print "$_ matched\n";
        }
$i++;
}

Upvotes: 0

NorthGuard
NorthGuard

Reputation: 963

I don't think regex is the best (or most readable) way to do this:

$str = "previous";
$input = "prev";
$length = length($input);

$strcheck = substr($str, 0, $length);
$incheck = substr($input, 0, $length);

if ($strcheck =~ $incheck && $length != 0) {
    // do something with $input
}

Upvotes: 1

Adam Batkin
Adam Batkin

Reputation: 52984

/^p(r(e(v(i(o(u(s)?)?)?)?)?)?)?$/

And just to double check that it works:

for (qw/p pr pre previous prevalent previse/) {
    $result = (/^p(r(e(v(i(o(u(s)?)?)?)?)?)?)?$/? "yes" : "no");
    print "Checking $_: $result\n";
}

Produces:

Checking p: yes
Checking pr: yes
Checking pre: yes
Checking previous: yes
Checking prevalent: no
Checking previse: no

Upvotes: 10

Related Questions