Problem
Find the positions of all occurrences of a pattern within a string. (Thanks @DonMcCormack )
Solution
Use the pattern matching functions
source = "this is a racecar and ere noon stressed desserts for Stanley Yelnats saw Anna was there";
palindrome = (Pat Regex( "[a-zA-Z][a-zA-Z ]{0,999}" )) >> firstpart +
(Pat Regex( "[a-zA-Z ]{0,1}" )) +
Expr( Reverse( firstpart ) );
list = {};
positions = {};
Pat Match(
source,
Pat Repeat(
(Pat Pos() >> location +
palindrome >> another +
Pat Test(
Insert Into( list, another );
Insert Into( positions, location );
1
)
)
|
Pat Len( 1 )
)
);
Show( list, positions );
list = {"a racecar a", "ere", "noon", "stressed desserts", "Stanley Yelnats", "saw Anna was", "ere"};
positions = {8, 22, 26, 31, 53, 69, 84};
Discussion
PatRepeat is a pattern matching function that repeats its pattern as long as it can. It can't skip over the undesired text without the PatLen(1) alternative that lets it ignore one character at a time until another instance of the desired pattern is found.
You can use a really simple pattern too:
source = "this is a racecar and ere noon stressed desserts for Stanley Yelnats saw Anna was there";
reallysimple = "is";
list = {};
positions = {};
Pat Match(
source,
Pat Repeat(
(Pat Pos() >> location +
reallysimple >> another +
Pat Test(
Insert Into( list, another );
Insert Into( positions, location );
1
)
)
|
Pat Len( 1 )
)
);
Show( list, positions );
list = {"is", "is"};
positions = {2, 5};