2009-12-09 4 views
2
souligne

Je ne sais pas s'il est vraiment facile et je suis hors de mon esprit ....expression régulière ne correspond pas à deux

Dans les expressions régulières de Ruby, comment faire correspondre les chaînes qui ne contiennent pas deux années consécutives underscores, c'est-à-dire "__".

Ex:

Matches: "abcd", "ab_cd", "a_b_cd", "%*##[email protected]+" 
Does not match: "ab__cd", "a_b__cd" 

-Merci

EDIT: Je ne peux pas utiliser la logique inverse, par exemple, la vérification des "__" chaînes et les exclure, étant donné que le besoin d'utiliser avec Ruby on Rails " validates_format_of() "qui attend une expression régulière avec laquelle correspondra.

+1

Je pense qu'il s'agit d'une erreur de conception dans 'validates_format_of'. Cela devrait prendre un prédicat général. Les expressions régulières sont un détail d'implémentation. – Svante

Répondre

3
/^([^_]*(_[^_])?)*_?$/ 

Tests:

regex=/^([^_]*(_[^_])?)*_?$/ 

# Matches  
puts "abcd" =~ regex 
puts "ab_cd" =~ regex 
puts "a_b_cd" =~ regex 
puts "%*##[email protected]+" =~ regex 
puts "_" =~ regex 
puts "_a_" =~ regex 

# Non-matches 
puts "__" =~ regex 
puts "ab__cd" =~ regex 
puts "a_b__cd" =~ regex 

Mais regex est surpuissant pour cette tâche. Un simple test de chaîne est beaucoup plus simple:

puts ('a_b'['__']) 
+0

Fonctionne bien, et a l'air si "pas complexe" (comparativement). Aussi, merci de prendre le temps d'écrire ces exemples. J'ai juste dû faire un "copier-coller" à ma session 'irb' pour les validations. En outre, une autre bonne réponse - http://stackoverflow.com/questions/1873436/regular-expression-for-not-matching-two-underscores/1873474#1873474 –

0

négative préanalyse

\b(?!\w*__\w*)\w+\b 

de recherche pour deux underscores consécutifs dans le mot suivant depuis le début du mot, et correspondent à ce mot si elle ne se trouve pas.

Edit: Pour accueillir autre chose que des espaces blancs dans le match:

(?!\S*__\S*)\S+ 

Si vous souhaitez recevoir un sous-ensemble de symboles, vous pouvez écrire quelque chose comme ce qui suit, mais il correspondra _cd de a_b__cd parmi autres choses.

(?![a-zA-Z0-9_%*#@+]*__[a-zA-Z0-9_%*#@+]*)[a-zA-Z0-9_%*#@+]+ 
+0

'\ w' ne contient pas' _'. – Gumbo

+0

@Gumbo: \ w signifie "caractère de mot", généralement [A-Za-z0-9_]. Remarquez l'inclusion du trait de soulignement et des chiffres – Andomar

+0

@Gumbo http://www.regular-expressions.info/charclass.html indique que '\ w' comprend' _' – Amarghosh

9

Vous pouvez utiliser préanalyse négative:

^((?!__).)*$ 

Le début-de-chaîne ^ et fin de chaîne $ sont importants, ils forcent un contrôle de « non suivie d'un double underscore » sur toutes les positions .

+1

Dans Ruby '^' et '$' sont respectivement le début et la fin de la ligne (pour les chaînes qui contiennent plusieurs lignes). Strictement, utilisez '\ A' et' \ Z' pour le début de chaîne et la fin de chaîne –

+0

Merci, fonctionne très bien. Mais, malheureusement, je ne peux sélectionner qu'une seule réponse, ainsi choisi "Mark Byers", comme sa solution est, bien, simple. Néanmoins, +1 à coup sûr. –

+0

Hier, je n'ai pas choisi votre réponse comme acceptée, parce que je ne connaissais pas la chose "lookahead négatif", mais maintenant je le fais. Et maintenant, je trouve ta réponse comme "wow". J'ai essayé de le modifier, mais je ne peux pas m'améliorer. Merci d'avoir répondu. –

2

La modification de votre logique serait-elle toujours valide?

Vous pouvez vérifier si la chaîne contient deux caractères de soulignement avec l'expression régulière [_] {2}, puis l'ignorer?

Questions connexes