Problem
Finden Sie die Positionen aller Vorkommen eines Musters in einer Zeichenfolge. (Vielen Dank @DonMcCormack )
Lösung
Verwenden Sie die Pattern-Matching-Funktionen
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 + // one or more first letters
(Pat Regex( "[a-zA-Z ]{0,1}" )) + // optional middle letter
Expr( Reverse( firstpart ) ); // the tail
list = {}; // places to
positions = {}; // keep results
Pat Match(
source,
Pat Repeat( // repeat *is* a loop, within the source string
(Pat Pos() >> location + // capture current position in string
palindrome >> another + // capture the text of the palindrome match
Pat Test( // this function runs some JSL to see if the current position matches
Insert Into( list, another );// the JSL saves
Insert Into( positions, location );// two answers
1 // pattest returns 1(OK) because we are not actually testing anything...just wanted to run some JSL
)//
)
| // above adds to list, below skips forward a letter to try again
Pat Len( 1 ) // this bit is more important than it looks; it matches all the text that isn't interesting
)
);
Show( list, positions );
list = {"ein Rennwagen a", "vor", "Mittag", "gestresste Nachspeisen", "Stanley Yelnats", "sah Anna war", "vor"};
Positionen = {8, 22, 26, 31, 53, 69, 84};
Diskussion
PatRepeat ist eine Pattern-Matching-Funktion, bei der das Pattern so lange wie möglich wiederholt wird. Der unerwünschte Text kann nicht übersprungen werden, ohne die Alternative PatLen (1), bei der jeweils ein Zeichen ignoriert wird, bis eine andere Instanz des gewünschten Musters gefunden wird.
Sie können auch ein wirklich einfaches Muster verwenden:
source = "this is a racecar and ere noon stressed desserts for Stanley Yelnats saw Anna was there";
reallysimple = "is";
list = {}; // places to
positions = {}; // keep results
Pat Match(
source,
Pat Repeat( // repeat *is* a loop, within the source string
(Pat Pos() >> location + // capture current position in string
reallysimple >> another + // capture the text of the match
Pat Test( // this function runs some JSL to see if the current position matches
Insert Into( list, another );// the JSL saves
Insert Into( positions, location );// two answers
1 // pattest returns 1(OK) because we are not actually testing anything...just wanted to run some JSL
)//
)
| // above adds to list, below skips forward a letter to try again
Pat Len( 1 ) // this bit is more important than it looks; it matches all the text that isn't interesting
)
);
Show( list, positions );
list = {"is", "is"};
Positionen = {2, 5};