2011-08-31 2 views
0

Je vais essayer de mieux m'expliquer ;-). J'utilise RegexBuddy pour essayer de trouver la solution. La cible est JavaScript dans un widget Konfabulator.JavaScript syntaxe RegExp question

La chaîne que je dois analyser est:

+++++++++++++++++++++ RUNWAY ++++++++++++++++++++++++++++++ 
1A1093/11 VALID: 1107140300 - 1108301500 
    DAILY 0300-1500 
    WIP 90M S OF RWY 08/26 AT E, W1, W2. 
    NO RESTRICTION DRG TKOF/LDG OR TAX. 
1A994/11 VALID: 1106201300 - 1112312059 
    PAPI RWY 08 NOT OPR WHEN ILS APCH IN USE. OPR WHEN VIS APCH IN 
    USE. 
1A987/11 VALID: 1106190615 - UFN 
    ILS DME RWY 08 BC 110.90MHZ CH46X OPR. 
+++ 

Le résultat final devrait être les trois sous-chaînes suivantes:

sous-chaînes 1)

1A1093/11 VALID: 1107140300 - 1108301500 
    DAILY 0300-1500 
    WIP 90M S OF RWY 08/26 AT E, W1, W2. 
    NO RESTRICTION DRG TKOF/LDG OR TAX. 

sous-chaînes 2)

1A994/11 VALID: 1106201300 - 1112312059 
    PAPI RWY 08 NOT OPR WHEN ILS APCH IN USE. OPR WHEN VIS APCH IN 
    USE. 

Substring 3)

1A987/11 VALID: 1106190615 - UFN 
    ILS DME RWY 08 BC 110.90MHZ CH46X OPR. 

Comme vous pouvez le voir chaque section commence par quelque chose de similaire à "1A987/11 VALIDE:" que je trouve en utilisant cette expression rationnelle:

[0-9A-Z]{3,6}/\d{2}\s{1,3}VALID: 

Chaque section se termine avec la "1A987/11 VALIDE:" de la section suivante ou "+++" que je trouve en utilisant cette expression rationnelle:

([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:)|(\+{3}) 

les caractères sont entre [\ s \ s] +? la "." ne fonctionne pas pour une raison quelconque.

Ainsi, le regex complet est:

[0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:[\s\S]+?(([0-9A-Z]{3,6}/\d{2}\\s{1,3}VALID:)|(\+{3})) 

Maintenant, depuis la fin de 1 est le sous-chaîne début de 2 sous-chaîne, RegexBuddy ne trouve pas 2 sous-chaîne, sous-chaîne seulement 1 et 3 sont trouvés.

Je cherche un moyen de trouver les 3 sous-chaînes, donc un moyen de trouver la fin de chaque sous-chaîne, mais de l'exclure de la chaîne elle-même.

+0

S'agit-il d'un décodeur NOTAM? –

Répondre

0

Je ne suis pas sûr à 100% de ce que votre deuxième VALID: fait là, mais je pense que la deuxième partie de votre expression régulière, après le "|" (ou) où vous semblez que vous essayez de capturer le cas "UFN", semble manquer quelque chose pour capturer l'UFN. Je ne connais pas la gamme complète des possibilités pour cette séquence, ou quelle implémentation de regex vous utilisez, mais si vous capturez des majuscules avec [AZ], vous auriez besoin de ce dernier groupe ([AZ] {3 }), ou utilisez le symbole alphanumérique générique après le slash à la place d'un plus.

0

Cela dépend de la langue dont nous parlons ici, mais l'expression régulière suivante a fonctionné pour moi en Perl avec l'extension s qui traite les fins de lignes comme des caractères normaux.

([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:.+?)([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:.+?)([0-9A-Z]{3,6}/\d{2}\s{1,3}VALID:.+?)(\+{3}) 

Si vous essayez de trouver un certain nombre de sections vous VALABLE devriez faire une boucle qui dépend de la langue.

Notez que j'ai réduit le [0-9]|[A-Z] en [0-9A-Z] et que j'ai copié le premier modèle (...) 3 fois.

+0

Cela a fonctionné dans RegexBuddy mais je n'ai pas réussi à le faire fonctionner en JavaScript. J'ai abandonné et résolu d'une autre manière. 10x pour toute l'aide. – Erez

+0

+1 serait apprécié. – Gray

0

Je ne suis pas tout à fait sûr de ce que l'analyseur regex que vous utilisez, mais donner cette bête un coup:

((?:(?:[0-9]|[A-Z]){3,6}/\d{2}\s{1,3}VALID:.+?)(?=(?: \+\+\+$|(?:[0-9]|[A-Z]){3,6}/\d{2}))) 

Il utilise lookaheads positif, il peut ou peut ne pas fonctionner pour vous.

Edit: Voici un test sur plusieurs lignes en JavaScript:

var match, regex = /([0-9A-Z]{3,6}\/\d{2}\s{1,3}VALID:[\s\S]+?)(?=(?: \+{3}$|(?:[0-9A-Z]{3,6}\/\d{2})))/g; 
var s='+++++++++++++++++++++ RUNWAY ++++++++++++++++++++++++++++++\n\ 
1A1093/11 VALID: 1107140300 - 1108301500 \n\ 
    DAILY 0300-1500 \n\ 
    WIP 90M S OF RWY 08/26 AT E, W1, W2. \n\ 
    NO RESTRICTION DRG TKOF/LDG OR TAX. \n\ 
1A994/11 VALID: 1106201300 - 1112312059 \n\ 
    PAPI RWY 08 NOT OPR WHEN ILS APCH IN USE. OPR WHEN VIS APCH IN \n\ 
    USE. \n\ 
1A987/11 VALID: 1106190615 - UFN\n\ 
    ILS DME RWY 08 BC 110.90MHZ CH46X OPR. +++'; 

while (match=regex.exec(s)){ 
    alert(match[0]); 
} 
1

La façon dont je lis votre question, les faits importants sont:

  1. chaque match comprend deux lignes ou plus;
  2. le début de la première ligne correspond au motif que vous avez donné; et
  3. chaque ligne suivante commence par des espaces.

Voilà comment j'exprimer que comme regex:

/^[A-Z0-9]{3,6}/[0-9]{2}[ \t]+VALID:.*(\r?\n[ \t]+.*)+/mg 

Remarquez comment je [ \t]+ au lieu de \s+ avant la VALID: et au début des lignes suivantes, pour correspondre uniquement le horizontal caractères d'espaces (espaces et/ou tabulations). Ensuite, j'ai utilisé \r?\n pour faire correspondre les séparateurs de ligne (style DOS \r\n ou Unix-style \n). De cette façon, je ne fais jamais plus que ce dont j'ai besoin, ce qui rend l'expression rationnelle plus efficace et plus facile à écrire et à déboguer.

Le m à la fin active le mode multiline, ce qui permet à l'ancre ^ de correspondre au début d'une ligne. Le g active le mode global, ce qui vous permet de trouver tous les résultats, pas seulement le premier. Par ailleurs, la raison pour laquelle vous avez dû utiliser [\s\S] au lieu de . est que JavaScript n'a pas de mode "single-line" ou "DOTALL", contrairement à la plupart des autres expressions regex. Il n'y a aucun moyen de faire correspondre le . un retour chariot (\r) ou un saut de ligne (\n). Mais c'est une autre chose que vous n'avez pas à faire si vous faites correspondre les séparateurs de ligne explicitement, comme je l'ai fait.