12
votes

Répétitions séparées par des virgules

J'ai une très longue regex pour correspondre à une entrée dans une liste que je traite. La liste doit être une ou plusieurs de ces entrées, séparées par des virgules. Considérons une regex: xxx

pour l'entrée. Pour correspondre à ma liste séparée par des virgules, je fais correspondre à quelque chose comme ceci: xxx

(Ça semble particulièrement stupide avec ma méchante regex au lieu du court que j'ai utilisé ici pour L'exemple)

Je pense qu'il doit y avoir une meilleure façon que d'avoir deux copies de l'entrée - une fois pour la première entrée, encore une fois pour et suivez les paires de virgules / d'entrée.


0 commentaires

4 Réponses :


4
votes

Quelque chose comme ça peut-être:

(                       # start of parent capture
  (?!=^|,)                # look ahead and find either the start of a line or a comma
  ([abc123])              # actual pattern to look for (token)
)+                      # say this whole pattern is repeatable


8 commentaires

Je ne pense pas que vous voulez le ! dans votre look à venir (ce qui est pour un regard négatif sur l'avenir), mais un look à venir ne correspond pas à un personnage, donc cela ne correspond pas. Vous devriez aller bien sans lookahead (?: (?: ^ | |,) ([A-C1-3])) +


@ jswolf19: J'utilise cela pour éviter le personnage en serrant dans le match. Je suppose que la préférence personnelle. - La combinaison me donne également à la fois le premier match et le reste. (Sans cela, je n'aurai que le premier jeton, soit le 2e vers l'avant)


Je sais que vous ne voulez pas le «,» dans le match, mais il doit être égalé: si vous avez 'A, 1', votre regex ne le correspondra pas. Le lookahead voit le ',', mais il y a toujours là quand vous essayez de faire correspondre le 1 parce que le lookahead ne jette pas le «,». Vous avez besoin d'un groupe de non-capture pour ce (?:) .


@jswolf: Pas sûr Ce que vous voulez dire ? Votre méthode ne me donne que le dernier match. (Dans votre exemple, le début de la ligne correspondrait en premier, puis la virgule compte vers le prochain match)


Enlevez le drapeau global, et votre ne correspond pas La chaîne entière est ce que je veux dire. Nifty Site, cependant.


@ jswolf19 est correct, (?! = ^ | <,) est un lookahead négatif pour = suivi du début de la chaîne (qui est impossible) ou une virgule. Être un négatif lookahead, il réussira toujours sans jamais essayer le , alternatif.


@Alan: (?! =) est un regard négatif en avant, où le signe égal est parle de la syntaxe. Où comme (?! <) serait un look derrière.


Désolé, mais non. Lookahead négatif est formé à partir de la version positive, non par Ajout A ! , mais par remplaçant le = avec elle . Lookbehind (une fonctionnalité beaucoup "plus jeune") ajoute << / code> à la syntaxe Lookahead, mais négatif lookbehind est ensuite formé de la même manière que le regard négatif: en remplaçant le =. avec ! .



7
votes

On dirait que vous voulez Backreferences . xxx

aussi, juste fyi, [abc] | [123] est équivalent à [ABC123] .


EDIT: Basé sur votre édition, je pense que j'ai mal compris ce que vous essayiez de faire. Essayez ceci: xxx

ou si vous souhaitez être moins restrictif: xxx

Ceci correspond aux cordes de caractères non-virgules séparé par des virgules. Une approche plus simple serait simplement une correspondance globale pour [^,] + par lui-même. En JavaScript, cela ressemblerait à ceci: xxx

ou vous pouvez simplement diviser les virgules: xxx


4 commentaires

Cela va dire que le prochain jeton doit être identique à celui précédent, non pas qu'il doit correspondre au modèle. (Je ne sais pas que c'est ce que l'OP veut, ils sont simplement curieux s'ils ont besoin de spécifier le motif deux fois [je pourrais être faux ...])


@Brad: N'est-ce pas ce qu'il va? Peut-être que je suis confus.


@Justinemorgan: Peut-être que tu as raison. Je l'ai lu comme "Dois-je spécifier le modèle à rechercher deux fois?", Et "sinon, comment puis-je éviter de le faire".


J'ai édité ma question. Je cherche vraiment simplement un moyen d'étendre un modèle à une liste séparée par des virgules.



0
votes

Dans mon cas, je teste toute la ligne.

var secs = val.split(/(?<=S\d+)(,\s*|\s+)/i);


0 commentaires

1
votes

Je ignore les défis en matière de capture de groupe et je traite ce n'est qu'un problème de validation, c'est-à-dire si la chaîne donnée est un CSV valide pour mon cas d'utilisation ou non em>.

La réponse la plus simple est xxx pré>

Ceci permet toutefois quelques cas qui peuvent ne pas être souhaitables p> xxx pré>

pour traiter ces cas, vous pouvez utiliser P>

^                     # don't allow leading invalid values
((
  ^(?!,)              # beginning, not starting with a comma
|                     # OR
  (?!^),              # not beginning, need a comma             
)(                    # followed by
  [abc]+|[123]+       # pattern for your valid values
))+                   # one or more times
$                     # don't allow trailing invalid values


0 commentaires