2011-10-27 4 views
2

J'ai une trame de données qui se compose d'un grand nombre de chaînes de caractères composé de 0, 1 et N. Voici quelques exemples:Motif correspondant en utilisant des expressions régulières dans une chaîne de caractères

a = "10000000011111111" 
b = "11111111111111111" 
c = "11111110000000NNN" 
d = "00000000000000000" 
e = "00000001111111111" 
f = "11111000000000000" 

Im la recherche pour une manière d'identifier les chaînes qui consistent seulement en '0' et '1' sans 'N'present. Mon but ultime est de remplacer dans mon cadre de données d'origine «REC» dans les endroits où cette situation se produit. Semblable à ce qui a été fait dans ce question.

Le résultat de mes données ci-dessus serait:

a = "REC" 
b = "11111111111111111" 
c = "11111110000000NNN" 
d = "00000000000000000" 
e = "REC" 
f = "REC" 

La principale stratégie Ive employée (guidée par les réponses de la question précédente) pour atteindre mon objectif utilise gsub mais je ne peux pas obtenir un regex qui fonctionne pour ma sortie désirée. J'ai essayé trop d'itérations pour essayer ici, mais voici ma fonction la plus récente est la suivante:

markREC <- function(X) { 
gsub(X, pattern = "^(0)+.*(1)+$", 
     replacement = "REC?")} 

Cette fonction sera exécutée sur la trame de données avec lapply

L'autre stratégie Ive a essayé appuyé sur strsplit mais j'ai du mal à faire fonctionner celui-ci aussi. Je peux donner des exemples si les gens aimeraient les voir. J'imagine que ce serait simple pour certains experts en regex, mais après plusieurs heures d'essais, j'adore l'aide!

Répondre

2

Ehm Je ne suis pas sûr de ce que vous essayez d'atteindre avec votre regex.

^(0)+.*(1)+$ 

signifie effectivement:

de début de chaîne, au moins un jeu 0 suivi par quoi que ce soit, suivie d'au moins une 1 et l'extrémité de la chaîne. Donc ceci: 032985472395871 matchs :)

^(?=.*0)(?=.*1)[01]+$ correspondra uniquement lorsque la chaîne complète se compose de 0 et de 1 et il y a au moins un 0 et au moins un 1.

// ^(?=.*0)(?=.*1)[01]+$ 
// 
// Assert position at the beginning of the string «^» 
// Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=.*0)» 
// Match any single character that is not a line break character «.*» 
//  Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
// Match the character “0” literally «0» 
// Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=.*1)» 
// Match any single character that is not a line break character «.*» 
//  Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*» 
// Match the character “1” literally «1» 
// Match a single character present in the list “01” «[01]+» 
// Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+» 
// Assert position at the end of the string (or before the line break at the end of the string, if any) «$» 
+0

ce ne marche pas le travail tout à fait, car il capte des chaînes qui ont seulement 0 ou seulement 1 qui jaimerais exclure de ce groupe. J'ai édité la question avec ma sortie désirée. –

+0

@SamGlobus En fait, cela fonctionne parfaitement. Je ne suis pas sûr de ce dont vous parlez. – FailedDev

+0

oui juste à des chaînes similaires à celles des guillemets. Les chaînes seront dans un cadre de données et auront des longueurs différentes. –

0

La regex correcte est:

"[^N]*" 

Je crois. Cela correspondra à une chaîne de n'importe quelle longueur à moins qu'elle ne contienne un N.

+0

Cela correspond également à "" = chaîne vide. – FailedDev

+0

Eh bien, une chaîne vide est toujours une chaîne n'est-ce pas? – BicMacinaPimpHat

0

Essayez cette

^([01]*)[^01]+([01]*)$

Matches début de la chaîne, suivi de 0 ou plus 0/1 de, suivi d'au moins 1 caractère qui nest pas 0/1, suivi de 0 ou plus 0/1 de (suivi d'ici la fin de chaîne)

+0

Cela ne correspond pas 1111111111111 = pas ce que l'op veut. – FailedDev

+0

vous avez raison, mon mauvais :) J'étais trop occupé à se concentrer sur l'aspect «N», je n'ai pas remarqué qu'il ne devrait pas correspondre à des chaînes constituées uniquement de 1 – carpii

2

Pour correspondre à des chaînes ne contenant que 0 et 1 (et non des chaînes contenant, vous pouvez seulement 0 ou 1), faites:

grepl("^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", <string>) 

Pour quelques-uns de vos exemples:

> grepl("^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", a) 
[1] TRUE 

> grepl("^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", b) 
[1] FALSE 

> grepl("^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", c) 
[1] FALSE 

maintenant brancher ce dans gsub:

> gsub(a, pattern="^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", replacement="REC") 
[1] "REC" 

> gsub(b, pattern="^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", replacement="REC") 
[1] "11111111111111111" 

> gsub(c, pattern="^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", replacement="REC") 
[1] "11111110000000NNN" 

> gsub(d, pattern="^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", replacement="REC") 
[1] "00000000000000000" 

> gsub(e, pattern="^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", replacement="REC") 
[1] "REC" 

> gsub(f, pattern="^((0)+(1)+(0|1)+)|((1)+(0)+(0|1)+)$", replacement="REC") 
[1] "REC" 
Questions connexes