2016-08-04 23 views
0

Ich versuche eine Funktion zu finden, die die n-te Instanz eines Zeichens indexiert. Wenn ich beispielsweise die Zeichenfolge ABABABBABSSSDDEE habe und die 3. Instanz von A finden möchte, wie mache ich das? Was passiert, wenn ich die vierte Instanz ABSAS: Wie finde ich die n-te Instanz eines Zeichens/einer Gruppe von Zeichen innerhalb einer Zeichenkette?

ABAB A BB AB SSSDDEE

data HAVE; 
    input STRING $; 
    datalines; 
ABABABBASSSDDEE 
; 
RUN; 
+1

was haben Sie bisher versucht. hast du in 'Regex Lookaround' gelesen. 'SAS' verwendet' PERL' Regex-Engine. – gwillie

+1

Sie könnten auch FIND in einer do-Schleife für einfache Beispiele verwenden, obwohl regex der bessere Weg für komplexe Fälle ist ... – kl78

+0

@gwillie Kein 'Regex' soweit, aber ich werde es mir genauer ansehen ..... Ich habe benutzt 'index' und' find' mit einer Kombination von 'substr' in der Vergangenheit, aber diese Komplexität der nächsten Ebene wird wahrscheinlich Regex brauchen. Ty. –

Antwort

0
data _null_; 
findThis = 'A'; *** substring to find; 
findIn = 'ADABAACABAAE'; **** the string to search; 
instanceOf=1; *** and the instance of the substring we want to find; 
pos = 0; 
len = 0; 
startHere = 1; 
endAt = length(findIn); 
n = 0; *** count occurrences of the pattern; 
pattern = '/' || findThis || '/'; 
rx = prxparse(pattern); 
CALL PRXNEXT(rx, startHere, endAt, findIn, pos, len); 
if pos le 0 then do; 
    put 'Could not find ' findThis ' in ' findIn; 
end; 
else do while (pos gt 0); 
    n+1; 
    if n eq instanceOf then leave; 
    CALL PRXNEXT(rx, startHere, endAt, findIn, pos, len); 
end; 
if n eq instanceOf then do; 
    put 'found ' instanceOf 'th instance of ' findThis ' at position ' pos ' in ' findIn; 
end; 
else do; 
    put 'No ' instanceOf 'th instance of ' findThis ' found'; 
end; 
run; 
0

Hier finden will, ist eine Lösung, die die find() Funktion und eine do-Schleife innerhalb eines datastep verwenden. Ich nehme dann diesen Code und lege ihn in eine proc fcmp Prozedur, um meine eigene Funktion zu erstellen, die find_n() genannt wird. Dies sollte die jeweilige Aufgabe erheblich vereinfachen und die Wiederverwendung von Code ermöglichen.

die Daten definieren:

data have; 
    length string $50; 
    input string $; 
    datalines; 
ABABABBABSSSDDEE 
; 
run; 

Do-Loop-Lösung:

data want; 
    set have; 
    search_term = 'AB'; 
    nth_time = 4; 
    counter = 0; 
    last_find = 0; 

    start = 1; 
    pos = find(string,search_term,'',start); 
    do while (pos gt 0 and nth_time gt counter); 
    last_find = pos; 
    start = pos + 1; 
    counter = counter + 1; 
    pos = find(string,search_term,'',start+1); 
    end; 

    if nth_time eq counter then do;  
    put "The nth occurrence was found at position " last_find; 
    end; 
    else do; 
    put "Could not find the nth occurrence"; 
    end; 

run; 

Definieren Sie die proc fcmp Funktion:

Hinweis: Wenn die n-te Auftreten kann nicht gefunden werden, zurück 0.

options cmplib=work.temp.temp; 

proc fcmp outlib=work.temp.temp; 

    function find_n(string $, search_term $, nth_time) ;  

    counter = 0; 
    last_find = 0; 

    start = 1; 
    pos = find(string,search_term,'',start); 
    do while (pos gt 0 and nth_time gt counter); 
     last_find = pos; 
     start = pos + 1; 
     counter = counter + 1; 
     pos = find(string,search_term,'',start+1); 
    end; 

    result = ifn(nth_time eq counter, last_find, 0); 

    return (result); 
    endsub; 

run; 

Beispiel proc fcmp Nutzung:

Beachten Sie, dass diese doppelte Funktion aufruft. Das erste Beispiel zeigt die ursprüngliche Anforderungslösung. Das zweite Beispiel zeigt, was passiert, wenn eine Übereinstimmung nicht gefunden werden kann.

data want; 
    set have; 
    nth_position = find_n(string, "AB", 4); 
    put nth_position =; 

    nth_position = find_n(string, "AB", 5); 
    put nth_position =; 
run; 
+0

Warum der Downvote? –