2010-12-01 4 views
0

J'essaie de faire correspondre les motifs dans perl et ont besoin d'aide.Perl Pattern Matching Question

J'ai besoin de supprimer d'une chaîne tout ce qui correspond à [xxxx], c'est-à-dire d'ouvrir des éléments de parenthèse à l'intérieur de celui-ci - le premier crochet de fermeture qui se produit.

Je suis en train de se substituer à l'espace du support d'ouverture, les choses à l'intérieur, la première tranche de fermeture avec le code suivant:

if($_ =~ /[/) 
    { 
    print "In here!\n"; 
    $_ =~ s/[(.*?)]/ /ig; 
    } 

De même, je doivent correspondre à savoir équerre choses angulaires à l'intérieur-première fermeture angulaire support.

Je fais cela en utilisant le code suivant:

if($_ =~ /</) 
    { 
    print "In here!\n"; 
    $_ =~ s/<(.*?)>/ /ig; 
    } 

Ce ne semble d'une façon de ne pas travailler. Mon échantillon de données est comme ci-dessous:

'Joanne' <!--Her name does NOT contain "Kathleen"; see the section "Name"--> "'Jo'" 'Rowling', OBE [http://news bbc co uk/1/hi/uk/793844 stm Caine heads birthday honours list] BBC News 17 June 2000 Retrieved 25 October 2000 , [http://content scholastic com/browse/contributor jsp?id=3578 JK Rowling Biography] Scholastic com Retrieved 20 October 2007 better known as 'J K Rowling' ,<ref name=telegraph>[http://www telegraph co uk/news/uknews/1531779/BBCs-secret-guide-to-avoid-tripping-over-your-tongue html Daily Telegraph, BBC's secret guide to avoid tripping over your tongue, 19 October 2006] is a British <!--do not change to "English" or "Scottish" until issue is resolved --> author best known as the creator of the [[Harry Potter]] fantasy series, the idea for which was conceived whilst on a train trip from Manchester to London in 1990 The Potter books have gained worldwide attention, won multiple awards, sold more than 400 million copies and been the basis for a popular series of films, in which Rowling had creative control serving as a producer in two of the seven installments [http://www businesswire com/news/home/20100920005538/en/Warner-Bros -Pictures-Worldwide-Satellite-Trailer-Debut%C2%A0Harry Business Wire - Warner Bros Pictures mentions J K Rowling as producer ] 

Toute aide serait appréciée. Merci!

Répondre

1

$_ =~ /someregex/ ne modifiera pas $_

Juste une note, $_ =~ /someregex/ et /someregex/ font la même chose.

En outre, vous n'avez pas besoin de vérifier l'existence de [ou < ou la parenthèse groupement:

s/\[.*?\]/ /g;

s/<.*?>/ /g;

fera le travail que vous voulez.

Edit: a changé le code en fonction du fait que vous modifiez $ _

+0

Je suis confus. Laquelle de ces substitutions dites-vous fait quoi? – tchrist

+0

Notez que le? est important. Il dit à Perl de ne pas faire de correspondance gloutonne. Sinon, vous devrez faire correspondre "[asfs [safs] asfsd]" – mmccoo

+0

@tchrist Son code d'origine essayait de supprimer à la fois [...] et <...>. La ligne 1 supprime [...] et la ligne 2 supprime <...>. – harleypig

1
  • Les crochets ont une signification particulière dans la syntaxe des expressions régulières, afin de les échapper: /\[.*?\]/. (Vous n'avez pas non plus besoin des parenthèses ici, et faire une correspondance insensible à la casse est inutile.)

  • Cela fait longtemps que je n'ai pas eu à me battre avec Perl, mais je suis presque sûr que tester $ _ avec une regex modifiera aussi $ _ (même si vous n'utilisez pas s ///). Vous n'avez pas besoin du test de toute façon; il suffit de lancer le remplacement, et si le motif ne correspond à rien, alors il ne fera rien.

+0

Vous avez raison sur votre 2ème point. – marcog

+3

Une opération de correspondance de modèle ne modifie pas la chaîne correspondante. Si c'est le cas, vous ne pouvez pas faire correspondre les constantes, mais vous pouvez: '" REPORT "= ~/^ \ Q $ choice/i'. – tchrist

+0

Je ne m'attendais pas à ce qu'il modifie la chaîne * en soi *, mais plutôt à signaler le succès ou l'échec sur $ _ et ainsi écraser le $ _ qui a été fourni pour la correspondance. –

2

Vous devez utiliser:

1 while s/\[[^\[\]]*\]; 

Démo:

% echo "i have [some [square] brackets] in [here] and [here] today."| perl -pe '1 while s/\[[^\[\]]*\]/NADA/g' 
i have NADA in NADA and NADA today. 

Versus l'échec:

% echo "i have [some [square] brackets] in [here] and [here] today." | perl -pe 's/\[.*?\]/NADA/g' 
i have NADA brackets] in NADA and NADA today. 

La récurrence Je pars régulièrement comme un exercice pour le lecteur.:)


EDIT:Eric Strom aimablement fourni une solution récursive vous ne devez pas utiliser 1 while:

% echo "i have [some [square] brackets] in [here] and [here] today." | perl -pe 's/\[(?:[^\[\]]*|(?R))*\]/NADA/g' 
i have NADA in NADA and NADA today. 
+0

's/\\ [(:? [^ \\ [\\]] * | (R)) * \\]/NADA/g' –

+0

@Eric: ** GRANDE ** Merci!. – tchrist