1
votes

Essayer de capturer plusieurs groupes dans regex tout en en sautant d'autres

J'essaye de créer une seule expression regex qui aura le résultat suivant sur deux exemples de textes différents:

Exemple 1

  • Exemple de texte 1: "Nom de l'application: Nom de la personne"
  • Groupe capturé 1: "Nom de l'application"
  • Groupe capturé 2: "Nom de la personne"

Exemple 2

  • Exemple de texte 2: "Nom de l'application (1 facteur): Nom de la personne"
  • Groupe capturé 1: "Nom de l'application"
  • Groupe capturé 2: "Nom de la personne"

L'expression regex que j'ai trouvée est: (. *) (\ s \ (. * \))?: \ s (. *) Mais il ne semble pas capturer correctement et je ne vois pas pourquoi.

J'essaye ceci en Java sur Android (et j'utilise une double barre oblique pour échapper dans la chaîne)


2 commentaires

(\ s \ (. * \))? est le groupe 2, qu'il corresponde ou non à quelque chose (? le laisse être facultatif). Donc, vos correspondances sont dans le groupe 1 et le groupe 3. Vous pouvez créer un groupe non capturant (\ s \ (. * \))? via (?: \ S \ (. * \ ))? pour ne pas faire partie de l'indexation de groupe. Pensez également à rendre . * non gourmand (réticent) en y ajoutant . *? . sinon . * essaiera de faire correspondre la correspondance maximale possible.


Cela semble avoir résolu le problème.


3 Réponses :


2
votes

Je pense que ce que vous recherchez est quelque chose comme:

([A-Za-z0-9\s]*)(\s\(.*\))?:\s(.*)

Le (. *) dans le premier groupe que vous avez capture chaque caractère avec gourmandise. Vous devez spécifier quel type de caractères peut précéder le (. J'ai utilisé regex101.com pour tester, et cela semble fonctionner pour les cas que vous avez fournis.


2 commentaires

Votre réponse fonctionne avec mes exemples spécifiques, bien que le commentaire de Pshemo semble fournir une solution plus générale qui fonctionnera dans les cas extrêmes, comme s'il y avait d'autres caractères ou symboles contenus dans le premier groupe.


\ w couvre A-Za-z0-9 . Pensez à le remplacer simplement par \ w .



1
votes

Faites simplement une non capture de : comme ceci:

Pattern

([^:\n]+)\s*:\s*([^:\n]+)

Voir la démo ici .


0 commentaires

1
votes

Vous pouvez utiliser

^(.*?)(?:\s*\([^()]*\))?:\s*(.*)$

Voir la démo regex a >.

Détails

  • ^ - début de chaîne
  • (. *?) - Groupe de capture 1: zéro ou plusieurs caractères autres que les sauts de ligne, le moins possible
  • (?: \ s * \ ([^ ()] * \))? - un groupe facultatif non capturant correspondant à 1 ou 0 occurrences de
    • \ s * - 0+ espaces blancs
    • \ ([^ ()] * \) - un (, zéro ou plusieurs caractères autres que ( et ) puis )
  • : - un deux-points
  • \ s * - 0 ou plus d'espaces blancs
  • (. *) - Groupe de capture 2: aucun ou plusieurs caractères autres que les sauts de ligne, autant que possible
  • $ - fin de chaîne.


0 commentaires