2016-05-24 9 views
2

Ich versuche, einen einzelnen Leerraum zu finden, der von einer Ziffer auf jeder Seite in einer Zeichenfolge umgeben ist. Ich habe das folgende Beispiel konstruiert:Warum vermisst diese Regex einen einzelnen Leerraum zwischen zwei Ziffern?

library('stringr') 
str1 <- "1805.6 1-1 1" 
str_locate_all(str1, "\\s+")[[1]] 
str_locate_all(str1, "[[:digit:]]\\s[[:digit:]]")[[1]] 

Welche zurück:

str_locate_all(str1, "\\s+")[[1]] 
    start end 
[1,]  7 7 
[2,] 11 11 

str_locate_all(str1, "[[:digit:]]\\s[[:digit:]]")[[1]] 
    start end 
[1,]  6 8 
[2,] 10 12 

das ist, was ich zu sehen erwartet. Jetzt die gleiche Sache an eine andere Zeichenfolge zu tun:

str2 <- "1805.6 1 1 1" 
str_locate_all(str2, "\\s+")[[1]] 
str_locate_all(str2, "[[:digit:]]\\s[[:digit:]]")[[1]] 

Aber das scheint einer der Räume von Ziffern umgeben zu verpassen (beachten Sie, dass das zweite Muster gibt nur 2 Einträge):

str_locate_all(str2, "\\s+")[[1]] 
    start end 
[1,]  7 7 
[2,]  9 9 
[3,] 11 11 

str_locate_all(str2, "[[:digit:]]\\s[[:digit:]]")[[1]] 
    start end 
[1,]  6 8 
[2,] 10 12 

So ist die Frage ist, warum nicht das zweite Muster den mittleren Leerraum sehen, und eine Zeile mit 8 10 zurückgeben? Ich bin mir sicher, dass ich nichts von der Denkweise von regex sehe.

+3

Die Übereinstimmungen werden verbraucht. Versuchen Sie eine Suche nach überlappenden Regex http://stackoverflow.com/search?q=%5Br%5D+overlapping+regex –

+0

Ich finde diese Ausgabe interessant obwohl 'str_locate_all (str2," (? = (\\ d \\ s \ \ d)) ") [[1]]' Das Ende ist vor dem Anfang :) –

Antwort

3

Ihre Ziffer nach Leerzeichen wird nach dem Spiel verbraucht. Sie können also das Match nicht finden. In Ihrem Beispiel

Hinweis: - x angepasst Ziffern

1805.6 1 1 1 
    x^x 
     | 
    First match 

1805.6 1 1 1 
     ^
     | 
Once the regex engine moves forward, it cannot see backward(unless lookbehind is used). 
Here, first digit from regex is matched with space which is not correct so the match fails outright and next position is attempted. 

1805.6 1 1 1  
     x^x 
     ||Matches digit 
     |Matches space 
     Matches digit 
    (Second match) 

This goes on till end of string is reached 

Visualisieren hier

enter image description here

bezeichnet können Sie lookahead verwenden stattdessen als

> str_locate_all(str1, "\\d\\s(?=\\d)")[[1]] 
    start end 
[1,]  6 7 
[2,]  8 9 
[3,] 10 11 

Als lookahaeads von Null sind Breite, wir g und die Position um eins weniger als die tatsächliche Endposition.

+0

Danke für diese klare Erklärung. Verwandte Frage: Gibt es einen funktionalen Unterschied zwischen der Verwendung von [[: digit:]] 'vs.' \\ d'? Vielen Dank. –

+0

@BryanHanson nein ich glaube nicht (bis zu meinem Wissen) .. eine Sache ist dort, die ich beobachtet hatte ist '[[: digit:]]' 'wird hauptsächlich von DFA-Engine unterstützt – rock321987

+0

Danke. Es war auf einem Spickzettel, den ich hatte, also habe ich es benutzt. Ich werde in Zukunft mit der kürzeren Form gehen. –

Verwandte Themen