12
votes

À Perl, comment puis-je obtenir la sous-chaîne assortie d'une regex?

Mon programme Lisez d'autres programmes Code source et Colect Informations sur les requêtes SQL d'occasion. J'ai un problème avec l'obtention de sous-chaîne.

...
$line = <FILE_IN>;
until( ($line =~m/$values_string/i && $line !~m/$rem_string/i) || eof )
{
   if($line =~m/ \S{2}DT\S{3}/i)
   {

   # here I wish to get (only) substring that match to pattern \S{2}DT\S{3} 
   # (7 letter table name) and display it.
      $line =~/\S{2}DT\S{3}/i;
      print $line."\n";
...


3 commentaires

Merci à tous pour des approches rapides et diverses. J'ai essayé de les utiliser tous hier et aujourd'hui matin et / mais seulement $ et travaille pour moi. Merci également à (utiliser des avertissements stricts; usage;) indice qui m'a montré mon style d'improvisation. Aujourd'hui, je réalise aussi que je n'ai pas informé que je travaillais sous Windows (ma perle est: c'est Perl, V5.8.7 Construit pour le copyright MSWIN32-X86-MULTI-FLUIGHT 1987-2005, Larry Wall binaire Build 813 [148120] fournie par Activez www.activestate.com Construit le 6 juin 2005 13:36:37). Merci une fois de plus.


J'étais peu irritée après que "l'ignorance est un bonheur" dans mon visage, mais ça me pousse à ... Eh bien ... laissez simplement dire maintenant je sais ce que "capturant le groupe" signifie "paren / parenthèses" et cela fonctionne vraiment. S'il vous plaît ne commencez pas, je me sens déjà stupide. BTW, Y a-t-il un vote mondial professionnel pour renommer Perl à - je ne sais pas - Pearl? ;)


Il y avait déjà une langue nommée Perle, lorsque Larry Wall est allé chercher des noms.


6 Réponses :


8
votes

Il serait préférable de faire correspondre le modèle s'il suit de code>. Je suppose que les noms de table consistent uniquement des lettres ASCII. Dans ce cas, il est préférable de dire ce que vous voulez. Avec ces deux remarques, notez qu'une capture réussie de la correspondance de la réégalité de la liste contextuelle renvoie la ou les sous-chaînes correspondantes.

if ( $s =~ /FROM (?<table>[A-Z]{2}DT[A-Z]{3})/i ) {
    print $+{table}, "\n";
}


0 commentaires

22
votes

Utilisez regroupement avec des parenthèses et stockez le premier groupe.

AADTTAB


0 commentaires

3
votes

Utilisez un groupe de capture:

$line =~ /(\S{2}DT\S{3})/i;
my $substr = $1;


1 commentaires

Vérifiez toujours si la correspondance a réussi avant d'utiliser les variables de correspondance.



7
votes

Les parens vous permettront de saisir une partie de la regex dans des variables spéciales: 1 $, 2 $, 3 $ ... Donc:

$line = ' abc andtabl 1234';
if($line =~m/ (\S{2}DT\S{3})/i)   {   
    # here I wish to get (only) substring that match to pattern \S{2}DT\S{3}    
    # (7 letter table name) and display it.      
    print $1."\n";
}


0 commentaires

0
votes

$ & code> contient la chaîne correspondée par la dernière correspondance du modèle.

Exemple: P>

if($line =~m/ \S{2}DT\S{3}/i) {
    print $&."\n";
}


5 commentaires

Évitez d'utiliser $ et et le «$» et le $ »associé, ils causent une pénalité de performance sur toutes les regextes de votre code. Voir Perlre ( perdoc.perl.org/perlre.html ) Pour plus d'informations.


Juste la simple mention de $ & , n'importe où dans votre code, ralentira toutes les regex. Cela n'a même pas d'importance si vous utilisez réellement la valeur.


Au cours des études, j'avais l'habitude d'évaluer cette déclaration. Est-ce que tout le monde vérifie la mauvaise pratique de cette ($ et)? Jusqu'à 10% / 30% et peuvent partager des résultats?


Je pense que je me souviens de lire que $ & a été prévu pour être obsolète, parfois dans le futur.


Je pense qu'il y a peut-être eu des changements qui réduisent l'effet dans Perl 5.10



18
votes

Je préfère ceci: xxx

ceci

  1. scans $ line et capture le texte correspondant au modèle
  2. retourne "tous" les captures (1) à la "liste" de l'autre côté.

    Ce contexte pseudo-liste est de savoir comment nous attrapons le premier élément d'une liste. Il est fait de la même manière que les paramètres passés à un sous-programme. xxx

    note: : Cela dit, votre regex suppose trop du texte à être utile dans plus d'une poignée de situations. ne pas capturer aucun nom de table qui n'a pas de dt comme dans les positions 3 et 4 sur 7? C'est assez bon pour 1) Quick-and-sale, 2) Si vous êtes d'accord avec une applicabilité limitée .


2 commentaires

C'est vraiment le contexte de la liste, il n'y a rien de pseudo à ce sujet! La chose délicate consiste à utiliser une liste d'un élément. Capturer les résultats d'une opération dans une seule liste d'éléments peut être très pratique lorsque vous souhaitez forcer le comportement de contexte de liste de l'opérateur ou le sous-programme que vous appelez. My $ foo = @bar; est très différent de mon ($ foo) = @bar; et la distinction peut être très pratique.


Oh, ça vient à portée de main. Je l'utilise tout le temps. Je suppose que "pseudo" est une mauvaise façon de le mettre. Je sais qu'une liste d'une liste est toujours une liste, cela ressemble à un terrain terrible comme un scalaire - et c'est tout ce que j'essaie d'obtenir de toute façon.