essayer d'écrire une expression régulière pour correspondre aux modèles de code à barres GS1 ( https: //fr.wikipedia. Org / wiki / GS1-128 ), contenant 2 ou plusieurs de ces modèles ayant un identifiant suivi d'un certain nombre de caractères de données.
J'ai besoin de quelque chose que Lisible humain avec les identificateurs de Parens: (01) 12345678901234 (17) 501200 P> Données réelles: Mais doit correspondre non à ce code à barres lorsqu'il n'y a qu'un seul motif dans: P > Lisible humain: (01) 12345678901234 P> Données réelles: Il semble que ce qui suit devrait fonctionner: p> p> 0112345678901234177501200 CODE> P> 0112345678901234 CODE> P> // Remove {2,} and it will return the first match
var regex = /(?:01(\d{14})|10([^\x1D]{6,20})|11(\d{6})|17(\d{6}))/g;
var str = "011234567890123417501200";
console.log(str.replace(regex, "$4"));
// matches 501200
console.log(str.replace(regex, "$1"));
// matches 12345678901234
// but then the problem is it would also match single identifiers such as
var str2 = "0112345678901234";
console.log(str2.replace(regex, "$1"));
3 Réponses :
1st exemple strong> p> Exemple avec 1 $ $ $ 3 $ 3 $ 4 Je ne sais pas pourquoi dans matrice :) p> Mais vous voyez 1 $ - > abc
2 $ -> DEF $ 3 -> GHI $ 4 -> JKL P> P> var regex = /(?:01(\d{14})|10(\x1D{6,20})|11(\d{6})|17(\d{6})){2,}/g;
var str = "011234567890123417501200";
// test
console.log(str.replace(regex, "$1 1st "));
console.log(str.replace(regex, "$2 2nd "));
console.log(str.replace(regex, "$3 3rd "));
console.log(str.replace(regex, "$4 4th "));
Merci! Mais le [^ \ x1d] code> est d'arrêter la correspondance de données s'il existe un caractère de séparateur de groupe invisible comme on le voit ici: Condor.depaul.edu/sjost/lsp121/documents/asci-npr.htm Comment ferais-je annuler ce caractère?
Dans votre dernier exemple, les dernières sorties de la console: 1234567890123417501200 lorsqu'il ne devrait émettre que 12345678901234
C'est pourquoi j'ai dit semble fonctionne :) @jacobh pour nier sans [^] Utilisez \ x code> il nie la valeur hexagonale
On dirait que vous le mettez à nouveau mis à nouveau. Merci d'enquêter! On dirait que c'est de retour au problème initial, en ce sens qu'il ne renvoie aucun des matchs à l'exception du dernier match.
Vous feriez votre texte plus lisible si vous termineriez des phrases de temps en temps.
"Une barre oblique inverse et échappé dans la zone niée n'a pas de sens" i>: ce n'est pas vrai: la barre oblique inverse a une signification dans les classes naissées.
VOTRE REGEX est logiquement et syntialatiquement pour les expressions ordinaires compatibles Perl-compatibles (PCRE). Le problème que je crois que vous êtes confronté est le fait que JavaScript a des problèmes avec des groupes de capture répétés. C'est pourquoi la regex fonctionne bien une fois que vous avez pris le Ce que je recommanderais, c'est supprimer le quantificateur S'il vous plaît voir l'extrait ci-dessous: p> p> {2,} code>. En ajoutant le quantificateur, JavaScript sera sûr de revenir {2,} code> et ensuite vérifiant par programme. allumettes. Je sais que ce n'est pas idéal pour ceux qui sont de grands fans de regex, mais c'est la vie em>. P> var regex = /(?:01(\d{14})|10([^\x1D]{6,20})|11(\d{6})|17(\d{6}))/g;
var str = "011234567890123417501200";
// Check to see if we have at least 2 matches.
var m = str.match(regex);
console.log("Matches list: " + JSON.stringify(m));
if (m.length < 2) {
console.log("We only received " + m.length + " matches.");
} else {
console.log("We received " + m.length + " matches.");
console.log("We have achieved the minimum!");
}
// If we exec the regex, what would we get?
console.log("** Method 1 **");
var n;
while (n = regex.exec(str)) {
console.log(JSON.stringify(n));
}
// That's not going to work. Let's try using a second regex.
console.log("** Method 2 **");
var regex2 = /^(\d{2})(\d{6,})$/;
var arr = [];
var obj = {};
for (var i = 0, len = m.length; i < len; i++) {
arr = m[i].match(regex2);
obj[arr[1]] = arr[2];
}
console.log(JSON.stringify(obj));
// EOF
Merci d'avoir confirmé qu'il s'agissait d'un problème spécifique JavaScript! C'est ce que j'espérais ne pas être le cas, mais le seul qui a eu sens à moi avoir vu qu'il fonctionnait correctement dans Ruby, avec l'utilitaire en ligne Ruby Regex: rubular.com connaissez-vous n'importe où qui documente les" problèmes avec des groupes de capture répétés "dans JavaScript?
Je ne connais aucun endroit qui indique explicitement que le moteur JavaScript Regex ne le fait pas correctement; Cependant, différentes langues ont des réputations différentes avec leur respect à des expressions régulières. La réputation de JS n'est pas si bonne. J'ai trouvé cette page ( rexegg.com/regex-javascript.html#critplied) Ce qui explique certains des problèmes courants de JS avec regex et propose une bibliothèque pouvant être utile.
@Grisza Nice! Merci d'avoir partagé.
La raison en est que les groupes de capture ne donnent que le dernier match par ce groupe particulier. Imaginez que vous auriez deux codes à barres dans votre séquence qui ont à la fois le même identifiant Un moyen simple, mais pas si élégant, est de supprimer le Enfin, comme vous ne savez pas quel identifiant sera trouvé pour la première et deuxième match, vous devez reproduire Voici le code amélioré appliqué à votre exemple de chaîne: p> P>
01 code> ... maintenant, il devient évident que 1 $ code> ne peut pas se référer aux deux en même temps. Le groupe de capture conserve uniquement la deuxième occurrence. {2,} code> et répétez plutôt le motif d'expression régulier pour correspondre au second code à barres. séquence. Je pense que vous devez également utiliser le ^ code> (début de l'ancrage de chaîne) pour vous assurer que la correspondance est au début de la chaîne, sinon vous pourriez récupérer un identifiant à mi-chemin d'une séquence non valide. Après le motif d'expression régulier répété, vous devez également ajouter . * Code> si vous souhaitez ignorer tout ce qui suit après la deuxième séquence, et ne vous y retournerez pas lorsque vous utilisez remplacer code> . P> 1 $ $ 3 $ 3 $ 4 code> dans votre Remplacer , sachant que l'une de ces quatre sera une chaîne non vide. Idem pour le deuxième match: 5 $ 6 $ 7 $ 8 $ 8 $ code>. P> var str = "011234567890123417501200";
var regex = /(?:01(\d{14})|10([^\x1D]{6,20})|11(\d{6})|17(\d{6})|(.))/g;
// 1: ^^^^^^ 2: ^^^^^^^^^^^^^ 3: ^^^^^ 4: ^^^^^ 5:^ (=failure)
var result = [], grp;
while ((grp = regex.exec(str)) && !grp[5]) result.push(grp.slice(1).join(''));
// Consider it a failure when not at least 2 matched.
if (result.length < 2) result = [];
console.log(result);
Merci d'avoir répondu! J'aime ta pensée, mais je viens de trouver une autre idée, basée partiellement sur votre idée de la dupliquer deux fois deux fois, mais j'ai fait du deuxième groupe un regard sur l'avenir: (?: 01 (\ d {14 }) | 10 ([^ \ x1d] {6,20}) | 11 (\ d {6}) | 17 (\ d {6})) (? = 01 (\ d {14}) | 10 ( [^ x1d] {6,2 0}) | 11 (\ d {6}) | 17 (\ d {6})) code> et quand il semble que cela semble toujours retourner tous les allumettes! Merci pour la réponse et inspiration!
Mais alors le remplacer code> que vous avez utilisé donnera un résultat qui comprendra plus que la correspondance.
Vous avez raison, oui, qui semble donner plus que ce qui est nécessaire pour 1 $, bien que avec 4 $, cela fonctionne correctement ... étrange. Darn, si proche! Merci!
Le problème principal que je vois avec votre solution d'origine est que cela ne fonctionne que s'il ya deux matchs dans le code à barres, qui fonctionne pour mon exemple donné, mais en réalité, il peut y avoir plus de 2 matchs dans un code à barres, raison pour laquelle j'avais Utilisé {2,} code> au lieu de {2} code>. Dupliquer le schéma autant de fois que possible les correspondances semblent excessives et difficiles à maintenir. Pour cette raison, je pourrais favoriser une autre solution.
C'est ce que j'ai écrit près de la fin de ma réponse. Si vous avez besoin d'un nombre dynamique de matchs, vous devez faire boucle. La boucle à travers les correspondances est-elle une solution acceptable pour vous? Si tel est le cas, je peux fournir cela, c'était juste que j'ai eu l'impression lorsque vous avez parlé des paramètres de configuration de RegEx, votre configuration ne permet pas de travailler avec quoi que ce soit d'autre qu'une seule regex -Replace qui fait tout cela.
Quoi qu'il en soit, j'ai ajouté une solution basée sur la boucle à ma réponse.
Impressionnant! Merci! Mais alors comment dites-vous quel groupe de match le résultat vient?
Les groupes sont dans le tableau code> GRP code>, à partir de l'index 1, car à l'index 0, vous trouvez la correspondance complète. Un seul des groupes de capture peut être une chaîne non vide à la fois, vous pouvez simplement ignorer la chaîne à l'index 0 et rejoindre les autres avec grp.slice (1) .join ('') code> . Si vous souhaitez tester un groupe individuel, do si (GRP (i)! == '') ... code>.
Quel est le match attendu?
J'ai modifié la question pour illustrer ce que sont les matchs. Merci!
Est
0112345678901234177501200 code> chaîne ou numéro? Sont01 code> et17 code> constantes?01123456789012341750120000 Une chaîne renvoyée à partir du scanner de code à barres et de 01 et 17 sont des identifiants, comme indiqué dans la spécification GS1-128 indiquant ce que le type de données sera et le nombre de caractères qu'il contiendra.
Avez-vous essayé de créer un objet dans lequel les noms de propriétés sont la séquence de code et les valeurs le
.length code> de la chaîne attendue adjacente à AI? Ensuite, vérifiez la chaîne pour paires de touches, de valeur de valeur?Je ne suis pas sûr de suivre ... Dites-vous de ne pas utiliser regex? Je dois utiliser Regex car il provient d'un paramètre de configuration différent par client dans notre base de données.
var correspondances = {"01": / 01 (? = \ d {14}) /, "17": 17 (? = \ d {6}) /} code>, correspond à chaque propriété, Valeur ou retourfaux code>. Vous pouvez également utiliser une fonction et.Every () code> qui retournetrue code> oufalse code> pour passer[correspondances] code>, Itération de biens et de valeurs pour créerREGEXP () code> des paramètres passés. Pouvez-vous décrire un motif spécifique? Quelles sont ou parties deregexp code>?C'est-à-dire, cassez le
REGEXP code> dans les portions où vous êtes certain que le code code> correct Boolean code> est renvoyé, au lieu d'essayer d'utiliser un seulRegexp code>var fn = fonction (str, re) {return re.Every (fonction (regex) {retour regex.test (str)})}; fn (str, [/ 01 (? = \ d {14}) /, / 17 (? = \ d {6}) /]) code>Oui, c'est ce que j'essayais de faire dans la dernière partie de mon poste mis à jour, où je mentionne que tout fonctionne correctement si je viens de supprimer le
{2,} code>, mais j'essaie de comprendre Pourquoi. Il semble que cela reconnaisse qu'il y a deux matches, car il retournera le deuxième match (4 $), mais pour une raison quelconque, il reconnaît qu'il a deux matchs, mais cela ne retournera pas le premier des deux allumettes.Est le problème
: code>? ExaminerREGEXP code>, est-ce qu'il n'y a qu'un seul groupe de capture? Vous pouvez obtenir des correspondances une à la fois en utilisant.match () code>