espressione regolare:Per estrarre una sottostringa tra due tag in una stringa

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

  •  08-06-2019
  •  | 
  •  

Domanda

Ho un file nel seguente formato:

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

Vorrei prendere il Data I want da tra il [Start] E [End] tag utilizzando una Regex.Qualcuno può mostrarmi come si potrebbe fare?

È stato utile?

Soluzione

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

Si spera che questo dovrebbe eliminare il problema [start] E [end] anche i marcatori.

Altri suggerimenti

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

Zhich inserirà il testo al centro all'interno di un'acquisizione.

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

Ho avuto un problema simile per un po' e posso dirti che questo metodo funziona...

Una discussione più completa sulle insidie ​​​​dell'utilizzo di una regex per trovare tag corrispondenti può essere trovata all'indirizzo: http://faq.perl.org/perlfaq4.html#How_do_I_find_matchi.In particolare, tieni presente che i tag annidati necessitano davvero di un parser completo per essere interpretati correttamente.

Tieni presente che la distinzione tra maiuscole e minuscole dovrà essere disattivata per rispondere alla domanda come indicato.In Perl, questo è io modificatore:

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

L'altro trucco è usare il file *? quantificatore che spegne l'avidità della partita catturata.Ad esempio, se hai un file non corrispondente [FINE] etichetta:

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

probabilmente non vuoi acquisire:

 Data i want [End] Data

Sebbene sia possibile utilizzare un'espressione regolare per analizzare i dati tra i tag di apertura e chiusura, è necessario riflettere a lungo e attentamente se questo è un percorso che si desidera seguire.Il motivo è la possibilità di annidare i tag:se i tag annidati potessero mai verificarsi o potessero mai verificarsi, si dice che il linguaggio non sia più regolare e le espressioni regolari cessino di essere lo strumento appropriato per analizzarlo.

Molte implementazioni di espressioni regolari, come PCRE o le espressioni regolari di Perl, supportano il backtracking che può essere utilizzato per ottenere questo effetto approssimativo.Ma PCRE (a differenza di Perl) non supporta il backtracking illimitato, e questo può effettivamente causare problemi in modi strani non appena si hanno troppi tag.

C'è un post del blog citato molto spesso che discute di questo in modo più approfondito, http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html (cercalo su Google e controlla la cache al momento, sembra che abbiano dei tempi di inattività)

Bene, se garantisci che ogni tag di inizio sia seguito da un tag di fine, allora funzionerebbe quanto segue.

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

Tuttavia, se hai un testo complesso come il seguente:

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

allora potresti riscontrare problemi con le espressioni regolari.

Ora il seguente esempio estrarrà tutti i collegamenti attivi in ​​una pagina:

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

Nel caso di cui sopra possiamo garantire che non ci sarebbero casi nidificati di:

'<a></a>'

Quindi, questa è una domanda complessa e non può essere risolta semplicemente con una risposta semplice.

Con Perl puoi racchiudere i dati che desideri tra () ed estrarli in seguito, forse altri linguaggi hanno una funzionalità simile.

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
}

Fai riferimento a questa domanda per estrarre il testo tra i tag con spazi e punti (.)

[\S\s] è quello che ho usato

Regex per abbinare qualsiasi carattere, comprese le nuove righe

Leggere il testo tra parentesi quadre [] cioè [Inizio] e [Fine] e convalidare l'array con un elenco di valori. jsfiddle http://jsfiddle.net/muralinarisett…/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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top