2012-12-10 1 views
2

Je semble avoir un blocage mental en ce qui concerne les expressions régulières, alors j'espère que vous pourrez m'aider.Expression régulière avec séparateur et partie optionnelle

J'ai une chaîne qui a ce format

.* :: .* :: .* 

Mais parfois, comme ceci:

.* :: .* 

Je veux capturer les 2 premiers groupes de personnages, comme celui-ci

(.*) :: (.*) :: .* 

Mais je ne sais pas comment modifier mon expression pour que les derniers :: et caractères soient optionnels. J'ai essayé d'utiliser des parenthèses et ?, mais je ne peux tout simplement pas le faire fonctionner comme vous le souhaitez.

Merci

+0

Vérifiez ma réponse révisée ci-dessous. Je l'ai eu fonctionné et l'ai testé complètement. Contrairement aux autres réponses ici, il permet aussi de faire du single: dans vos cordes sans problème, en ne recherchant que double ::. – Anton

Répondre

1

Got it!

(.*?) :: (.*?(?= :: |$)) 

Voici une ventilation de la façon dont cela fonctionne:

-> Cela permet d'isoler le premier lot de caractères avant le premier :: et enregistre dans le groupe 1 $.

(.*?) 

-> Ensuite, ce bloc fait deux choses. D'abord, il utilise. *? pour obtenir le deuxième lot de caractères. Après cela, l'assertion d'anticipation positive de largeur nulle (? = :: | $) requiert que les caractères se terminent par un autre :: ou $, la fin du texte, mais ne les inclut pas dans le groupe de correspondance, ce qui signifie seul le deuxième lot de caractères est enregistré à 2 $.

(.*?(?= :: |$)) 

J'ai testé en Objective-C par rapport à ces cordes avec succès:

  • "ABC :: DEF"
  • "ABC :: DEF :: GHI"
  • « A: B : C :: D: E: F "(ceci permet d'être seul dans les textes entre: :) ​​
  • " A: B: C :: D: E: F :: G: H: I "(cela permet single: être dans les textes entre: :) ​​
+0

C'est ce que suggérait à l'origine @Petar Ivanov, mais vous pouvez voir par mon premier commentaire que ça n'a pas vraiment marché. – coopersita

+0

J'ai été en mesure de trouver un RegEx correspondant exactement à ce que vous aviez demandé lors d'un test en Objective-C, veuillez voir ma réponse révisée. – Anton

+0

Oui, c'est totalement fait. Tu es un génie! Merci! – coopersita

2

C'est ce que vous voulez:

([^:]*) :: ([^:]*) (:: ([^:]*))? 

Les groupes auxquels vous accédez alors capturés sont 1, 2 et 4 (où 4 pourrait être vide).

EDIT:

Le .*? est non gourmand .*, à savoir qu'il correspond en caractères wild card que possible. Cela empêcherait le premier groupe de correspondre aux deux premiers modèles. Une autre option serait de remplacer .* par [^:]* si vous savez que le modèle ne contient pas :.

+0

Fermez, mais les premier et deuxième groupes sont groupés en un seul. 1 est '. * ::. *' Et 2 est le dernier '. *'. Cela ne fonctionne que lorsque le dernier motif est manquant. – coopersita

+0

hm, oui je vois ... permettez-moi de le corriger alors –

+0

Closer, mais maintenant 2 ne capture que le premier mot ... – coopersita

1

Qu'en est-il de quelque chose comme ça?

(.* ::){2}(?:::)? 

match deux choses suivi par ::, et le dernier peut avoir un :: en option.

+0

Également à proximité, mais cela ne fonctionne que lorsque j'ai les 3 groupes de caractères et les 2 séparateurs. Il ajoute le '::' à la fin de mes chaînes, aussi. – coopersita

Questions connexes