Expression régulière :Pour extraire une sous-chaîne entre deux balises dans une chaîne

StackOverflow https://stackoverflow.com/questions/1237

  •  08-06-2019
  •  | 
  •  

Question

J'ai un fichier au format suivant :

Data Data
Data
[Start]
Data I want
[End]
Data

J'aimerais saisir le Data I want d'entre les [Start] et [End] balises à l’aide d’une Regex.Quelqu'un peut-il me montrer comment procéder ?

Était-ce utile?

La solution

\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]

Espérons que cela devrait faire tomber le [start] et [end] des marqueurs également.

Autres conseils

\[start\](.*?)\[end\]

Ce qui placera le texte au milieu d'une capture.

$text ="Data Data Data start Data i want end Data";
($content) = $text =~ m/ start (.*) end /;
print $content;

J'ai un problème similaire depuis un moment et je peux vous dire que cette méthode fonctionne...

Une discussion plus complète sur les pièges liés à l'utilisation d'une expression régulière pour trouver des balises correspondantes peut être trouvée à l'adresse : http://faq.perl.org/perlfaq4.html#How_do_I_find_matchi.En particulier, sachez que les balises imbriquées ont vraiment besoin d'un analyseur complet pour être interprétées correctement.

Notez que la sensibilité à la casse devra être désactivée afin de répondre à la question comme indiqué.En perl, c'est le je modificateur:

$ echo "Data Data Data [Start] Data i want [End] Data" \
  | perl -ne '/\[start\](.*?)\[end\]/i; print "$1\n"'
 Data i want 

L'autre astuce consiste à utiliser le *? quantificateur qui désactive la gourmandise du match capturé.Par exemple, si vous avez un [fin] étiqueter:

Data Data [Start] Data i want [End] Data [end]

vous ne voulez probablement pas capturer :

 Data i want [End] Data

Bien que vous puissiez utiliser une expression régulière pour analyser les données entre les balises d'ouverture et de fermeture, vous devez réfléchir longuement et sérieusement pour savoir s'il s'agit d'un chemin que vous souhaitez emprunter.La raison en est le potentiel d’imbrication des balises :si des balises imbriquées peuvent se produire ou pourraient se produire un jour, le langage ne serait plus régulier et les expressions régulières cesseraient d'être l'outil approprié pour l'analyser.

De nombreuses implémentations d'expressions régulières, telles que PCRE ou les expressions régulières de Perl, prennent en charge le retour en arrière qui peut être utilisé pour obtenir cet effet approximatif.Mais PCRE (contrairement à Perl) ne prend pas en charge le retour en arrière illimité, ce qui peut en fait provoquer des pannes étranges dès que vous avez trop de balises.

Il existe un article de blog très fréquemment cité qui en parle davantage, http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html (Google pour cela et vérifiez le cache actuellement, ils semblent avoir des temps d'arrêt)

Eh bien, si vous garantissez que chaque balise de début est suivie d'une balise de fin, ce qui suit fonctionnerait.

\[start\](.*?)\[end\]

Cependant, si vous avez un texte complexe tel que celui-ci :

[start] sometext [start] sometext2 [end] sometext [end]

alors vous rencontreriez des problèmes avec les regex.

Maintenant, l'exemple suivant extraira tous les liens dynamiques d'une page :

'/<a(.*?)a>/i'

Dans le cas ci-dessus, nous pouvons garantir qu’il n’y aura pas de cas imbriqués de :

'<a></a>'

Il s’agit donc d’une question complexe qui ne peut pas être résolue simplement par une réponse simple.

Avec Perl, vous pouvez entourer les données souhaitées avec des () et les extraire plus tard, peut-être que d'autres langages ont une fonctionnalité similaire.

if ($s_output =~ /(data data data data START(data data data)END (data data)/) 
{
    $dataAllOfIt = $1;      # 1 full string
    $dataInMiddle = $2;     # 2 Middle Data
    $dataAtEnd = $3;        # 3 End Data
}

Reportez-vous à cette question pour extraire le texte entre les balises avec des espaces et des points (.)

[\S\s] est celui que j'ai utilisé

Regex pour correspondre à n'importe quel caractère, y compris les nouvelles lignes

Lire le texte entre crochets [] c'est-à-dire [Début] et [Fin] et valider le tableau avec une liste de valeurs. jsfiddle http://jsfiddle.net/muralinarisetty/r4s4wxj4/1/

var mergeFields = ["[sitename]",
                   "[daystoholdquote]",
                   "[expires]",
                   "[firstname]",
                   "[lastname]",
                   "[sitephonenumber]",
                   "[hoh_firstname]",
                   "[hoh_lastname]"];       

var str = "fee [sitename] [firstname] \
sdfasd [lastname] ";
var res = validateMeargeFileds(str);
console.log(res);

function validateMeargeFileds(input) {
    var re = /\[\w+]/ig;
    var isValid;
    var myArray = input.match(re);

    try{
        if (myArray.length > 0) {
            myArray.forEach(function (field) {

                isValid = isMergeField(field);

                if (!isValid){
                   throw e;                        
                }
            });
        }
    }
    catch(e) {        
    }

    return isValid;
}

function isMergeField(mergefield) {
    return mergeFields.indexOf(mergefield.toLowerCase()) > -1;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top