Re: search for nth occurrence of a pattern in a line
by davido (Cardinal) on May 17, 2006 at 08:13 UTC
|
The third occurence of a string can be found by stepping through your substring with index. Since ',' is a simple string, not a pattern, index is ideal.
On the other hand, if you really do want to search for a particular pattern, here's one way to do it with respect to finding the third comma, using a regexp:
use strict;
use warnings;
my $string = "a,bc,d,efg";
if( $string =~ m/(?:,[^,]*){2}(,)/ ) {
print $';
}
| [reply] [d/l] |
Re: search for nth occurrence of a pattern in a line
by ioannis (Abbot) on May 17, 2006 at 08:56 UTC
|
Here is a solution. The basic idea to count the times we
of the found pattern as we scan the string from left to right. Although we can compact the code into 2 short lines,
it is shown bellow longer and verbose.
# $n is the nth wanted occurence, as indicated by the question.
# $i holds how many times we found the pattern
my $str = ',n ,pple , d,y';
my ($n, $i) = 4;
$str =~ / , # we are searching for the , pattern
(?{ $i++}) # we found it again , increament $i
/xgc # retain last occurance on failure
for (1..$n);
# print position in string
print +($n == $i) ? pos($str) - 1
: 'not found';
| [reply] [d/l] |
Re: search for nth occurrence of a pattern in a line
by Praveen (Friar) on May 17, 2006 at 08:58 UTC
|
$str = "The, Sample, sents, kdsjf, jdfhj";
for (split(/,/, $str,3))
{
print ;
}
or
$cnt =0;
while($str =~ /(.*?),/g)
{
$cnt++;
print $&, if($cnt ==3);
}
| [reply] [d/l] [select] |
Re: search for nth occurrence of a pattern in a line
by parv (Parson) on May 17, 2006 at 08:31 UTC
|
You would start with searching this site via "Super search" for something like "nth character occurrence".
Otherwise, following algorithm comes to mind (untested; would be pleased to know of any errors) ...
keep a counter to count the number of occurrences of the pattern,
initially -1 (assuming 0-based indexing)
keep a marker to note the position of the pattern
run loop from the start of a line to its end
check if pattern exists
if not,
exit out of loop
else
check if counter is same the nth-place required
if yes,
exit out of loop
else,
increment the counter
set the marker to the start of the pattern
loop the loop from the marker + the length of the pattern + 1
at the end, equivalence of counter & desired nth occurrence will
give you the result.
| [reply] [d/l] |
Re: search for nth occurrence of a pattern in a line
by jesuashok (Curate) on May 17, 2006 at 08:11 UTC
|
| [reply] |
Re: search for nth occurrence of a pattern in a line
by GrandFather (Saint) on May 17, 2006 at 10:19 UTC
|
use strict;
use warnings;
my $pat = 'ono';
my $str = <<STR;
ono is the pattern to match. ono is found once in onono
STR
#123456789012345678901234567890123456789012345678901234
# 1 2 3 4 5
for my $count (1..4) {
if ($str =~ /(?:(?:(?!$pat).)*($pat)){$count}/) {
print "Match at $-[1] for count = $count\n";
} else {
print "No match for count = $count\n";
}
}
Prints:
Match at 0 for count = 1
Match at 29 for count = 2
Match at 50 for count = 3
No match for count = 4
Note that at least simple regex matches are fine in the pattern including look ahead and look back matches, but avoid capture groups.
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: search for nth occurrence of a pattern in a line
by japhy (Canon) on May 17, 2006 at 14:09 UTC
|
Sounds like an XY Problem to me. Why are you searching for the third occurrence of a comma in a string? Do you want to get at the fourth field in a comma-separated string? If so, use split().
| [reply] |
Re: search for nth occurrence of a pattern in a line
by duff (Parson) on May 17, 2006 at 18:26 UTC
|
In perl6 it's m:3rd/,/ and .pos will tell you at what position it matched. :-)
| [reply] [d/l] [select] |
Re: search for nth occurrence of a pattern in a line
by TedPride (Priest) on May 17, 2006 at 20:21 UTC
|
True, I suppose. How about:
use strict;
use warnings;
my ($str, $nth, $find, $p);
$str = "dsf,sdg,hjhgj,gjkh";
$nth = 3; $find = ',';
$str =~ m/(?:.*?$find){$nth}/g;
$p = pos($str) - length($find);
print substr($str, $p) if $p > -1;
That doesn't use either one :) | [reply] [d/l] |
Re: search for nth occurrence of a pattern in a line
by TedPride (Priest) on May 17, 2006 at 20:06 UTC
|
use strict;
use warnings;
my ($str, $nth, $p);
$str = "dsf,sdg,hjhgj,gjkh";
$p = -1; $nth = 3;
while ($str =~ /,/g) {
$p = pos($str) - length($&), last if !--$nth;
}
print substr($str, $p) if $p != -1;
Regex is better imho, since you don't know if you might want to do a pattern match some time in the future. | [reply] [d/l] |
|
|
pos($str) - length($&)? Ewwww. First of all, $& is a Curse, and second, you can just use $-[0] to get the same location.
while ($str =~ /,/g) { $p = $-[0], last if !--$nth }
| [reply] [d/l] [select] |