2010-07-19 4 views
7

Je dois faire correspondre 8 chiffres ou plus, dont la séquence peut inclure des espaces. Par exemple, tous les éléments ci-dessous correspondent à des correspondances valides.Ignorer les espaces blancs pour un match Regex

12345678 
1 2345678 
12 3 45678 
1234 5678 
12 34567 8 
1 2 3 4 5 6 7 8 

Au moment j'ai \d{8,} mais cela ne capturera un bloc solide de 8 chiffres ou plus.
[\d\s]{8,} ne fonctionnera pas car je ne veux pas que l'espace blanc contribue au nombre de caractères capturés.

Répondre

1

Waayy plus tard, mais cela a vraiment besoin de la bonne réponse à ce sujet, et une raison pour laquelle. Qui savait que cette question pourrait avoir une réponse si complexe, non? Lol. Mais il y a beaucoup de considérations entourant l'espacement dans regex.

Premièrement; Ne mettez jamais un espace dans une regex. Cela rendra votre regex illisible et impossible à maintenir. Souvenirs d'utiliser une souris pour mettre en évidence un espace pour s'assurer qu'il n'y avait qu'un seul espace vient à l'esprit. Cela va casser votre regex:    , mais ce ne sera pas: [   ], parce que la répétition dans une classe de caractères est ignorée. Et si vous avez besoin d'un nombre exact d'espaces, vous pouvez réellement voir cela dans une classe de caractères comme ceci: [ ]{3}. Versus accidents sans la classe de caractères comme ça:     {3} < - Ceci est en fait à la recherche de 5 espaces, woops!

Deuxième; Gardez l'option Freespacing (?x) à l'esprit, ce qui rend votre regex commentable et libre-spaceable. Vous ne devriez pas craindre que quelqu'un utilisant cette option puisse casser votre regex parce que vous avez décidé d'y mettre des espaces clavier aléatoires. En outre, (?x) va pas ignorer l'espace clavier lorsqu'il est dans une classe de caractères comme suit: [ ]. Il est donc plus sûr d'utiliser des classes de caractères pour vos espaces clavier.

Troisième; Essayez de ne pas utiliser \s dans ce scénario. Comme le souligne Omaghosh, il comprend également les nouvelles lignes (\r et \n). Le scénario que vous avez mentionné ne semble pas favoriser cela. Cependant, comme le souligne Omaghosh, vous voudrez peut-être plus que juste des espaces clavier. Donc, vous pouvez utiliser soit [ ], [\s-[\r\n]], ou [\f\t\v\u00A0\u2028\u2029\u0020] selon ce que vous voulez. Les deux derniers dans ces options sont la même chose, mais la soustraction de classe de caractères ne fonctionne que dans .NET et quelques autres saveurs étranges.

Quatrième; Ceci est un modèle généralement construit: (\s*...\s*)*.Cela n'a aucun sens. C'est la même chose: (\s*\s*...)* ou ceci: (\s*\s*\s*\s*...)*. Parce que le motif est répétitif. Le seul argument contre ce que je dis est que vous seriez sûr de capturer les espaces avant le .... Mais pas une seule fois n'est jamais vraiment voulu. Le pire scénario, vous pouvez voir ceci: \s*(...\s*)*

Omaghosh avait la réponse la plus proche, mais c'est la plus courte réponse:

Regex.Match(input, @"(?:\d[ ]*){8,}").Groups[0].Value; 

Ou ce qui suit, si nous prenons la question littéralement que les six options sont dans le même texte sur plusieurs lignes:

Regex.Match(input, @"(?m)^(?:\d[ ]*){8,}$").Groups[0].Value; 

Ou ce qui suit, si elle fait partie d'un plus grand regex et a besoin d'un groupe:

Regex.Match(input, @"...((?:\d[ ]*){8,})...").Groups[1].Value; 

Et ne hésitez pas à remplacer le [ ] avec une classe .NET Soustraction, ou une Non-.NET classe explicite des espaces:

@"(?:\d[\s-[\r\n]]*){8,}" 
// Or . . . 
@"(?:\d[\f\t\v\u00A0\u2028\u2029\u0020]*){8,}" 
+0

Excellente réponse! –

0
(\d{8,}\s+)*\d{8,} 

devrait fonctionner

+0

Test cela dans Expressio, il correspond uniquement '12345678' et aucun des autres exemples. –

+0

@Greg B: Je vois ce que tu veux dire. Je n'étais pas sûr. Pour être honnête, je ne pense pas que ce soit possible dans l'expression rationnelle 'vanilla', mais je suis sûr qu'il y a un truc pour le gérer. Une autre option consiste à supprimer tous les espaces avant d'appliquer le Regex. – leppie

13
(\d *){8,} 

Il correspond à huit ou plusieurs occurrences d'un chiffre suivi par zéro ou plusieurs espaces. Changez-le en

(*\d *){8,} #there is a space before first asterik 

pour faire correspondre les chaînes avec des espaces au début. Ou

(\s*\d\s*){8,} 

pour correspondre aux tabulations et aux autres caractères d'espace blanc (y compris les caractères de nouvelle ligne).

Enfin, en faire un groupe non-capture avec ?:. Ainsi, il devient (?:\s*\d\s*){8,}

+0

+1: Pas mal :) (texte de remplissage) – leppie

+1

+1 '\ s * \ d \ s * {8,}' est en fait '(\ s * \ d \ s *) {8,}' – TheVillageIdiot

+0

@TheVillateIdiot Le fixe déjà :) – Amarghosh

Questions connexes