2015-12-20 9 views
7

Sono un po 'all'oscuro del prossimo compito. Desidero selezionare un testo tra "che si trova all'interno di un tag ma non all'esterno del tag, ovvero una selezione all'interno di un'altra selezioneEspressione regolare, seleziona una porzione di testo all'interno di altri

Ho il tag successivo: < | e |> e voglio selezionare solo un testo se è tra "e" tra i tag.

< | bla bla bla "deve essere selezionato" non selezionato "selezionarlo troppo" |> "Non selezionata troppo"

penso qualcosa su

(\<\|)(\").*?(\")(\|\>) 

Ma non funziona.

+0

@nicael hai nemmeno letto la domanda? OP vuole selezionare i valori tra le virgolette solo se i suoi tag interni sono '<|' '|>' –

+0

Sì, non è un duplicato, non voglio selezionare alcun testo all'interno di "", voglio selezionare un testo che si trova all'interno "" e <| |> e il suo JS e C# – magallanes

+0

@ M.kazemAkhgary non importa, soluzione facilmente regolabile. Immagina solo che '<|' and '|>' sono altre citazioni e migliorare la regex. – nicael

risposta

4

Questo farà il lavoro in una sola espressione regolare:

(?<=<\|[^>]*)"[^"]*"

Oltre a un commento di nicael: Potrebbe essere possibile che l'input str ing non è taggato correttamente.Ciò contribuirà a:

(?<=<\|((?!\|>).)*)"[^"]*"

Se avete bisogno di usare con JavaScript:

(?=("[^"]*"[^"]*)*$)"[^"]*"(?=((?!<\|).)*\|>)

+0

Sembra fantastico, ma perché non funziona [lì] (http://regexr.com/3cet3)? Sul cellulare, non è possibile visualizzare l'errore. – nicael

+0

Trovato un problema nella regex: [this] (http://regexstorm.net/tester?p= (% 3f% 3c% 3d% 3c% 5c% 7c% 5b% 5e% 3e% 5d *)% 22% 5b% 5e% 22% 5d *% 22 & i =% 3c% 7c + bla + bla + bla +% 22should + essere + selezionato% 22 + non + selezionato +% 22select + it + troppo% 22 +% 3e +% 22not + selezionato + troppo % 22 +% 3c% 7c +% 22 test% 22 +% 7c% 3e +% 22wrong + corrispondenza% 22 +) non corrisponde correttamente. Ho sostituito prima |> con>, questo dovrebbe causare "non selezionato troppo" per corrispondere, anche se non è così. – nicael

+0

@nicael Ho aggiunto una regex che risolve il secondo problema. Il mio regex funzionerà con regex. Il tuo esempio di pugno mostra che l'aspetto dietro le asserzioni non è permesso in JavaScript. Scusate. Cos'è quello? C'è una regex che non supporta lo sguardo dietro? Cerco di trovare una soluzione che funzioni con le asserzioni look ahead. –

6

Ho ottenuto che corrisponda correttamente utilizzando due regex.

var input = '<|a "b"|>c "d"ef<|"g"h "i"|>"j"k l'; 
 
var output=input.match(/<\|(.*?)\|>/g) 
 
    .map(function(x){return x.match(/"(.*?)"/g)}) 
 
alert(output)

Come si può vedere, corrisponde correttamente "b", "g", "i".

Il principio:

  1. trovare tutte le partite di testo tra <| e |>
  2. per ogni partita dal primo passo, trovare partite di testo tra due apici.

(usato il regex dal second answer dalla questione linked)

+0

I grezzi '*' quantificatori mangeranno la prima coppia di '<|', '|>' se ne sono presenti diversi: https://regex101.com/r/wI4lF2/1 –

+0

@Jan hm, questo sembra essere il problema. Testato usando l'esempio di OP. – nicael

+0

@Jan modificato: come risposta citato javascript, usato :) – nicael

2

provare con look-sedere e guardare-aheads:

(?<=\<\|.)(\"[^"]*\")(?=.\|\>) 

Regular expression visualization

Ecco un live demo.

+0

Sbagliato! guarda [questo] (https://www.debuggex.com/r/X0X40tbmW4jSIEHd) esempio. – fardjad

+0

@fardjad oh, hai ragione. La risposta di Nicael fallisce anche nel tuo esempio. Hai suggerimenti migliori? –

+0

Sì, ma non con una singola regex, pubblicherò la mia soluzione tra un minuto. – fardjad

3

I can't think of a regular expression to match what you want in one shot ma non vedo il motivo per non farlo con due espressioni regolari:

var SAMPLE_STRING = '<| blah blah blah "should be selected" not selected "select it too" |> "not selected too" <| "select it" do not select this |> "don\'t select this one too"'; 
 

 
var matchAll = function matchAll(regexp, str) { 
 
    var lastIndex = regexp.lastIndex; 
 
    regexp.lastIndex = 0; 
 
    var result = []; 
 
    var match; 
 
    while ((match = regexp.exec(str)) !== null) { 
 
    result.push(match[0]); 
 
    } 
 
    regexp.lastIndex = lastIndex; // so this method won't have any side effects on the passed regexp object 
 
    return result; 
 
}; 
 

 
var withinTagsRegexp = /<\|([^|]|\|[^>])+\|>/g; 
 
var withinQuotesRegexp = /"[^"]+"/g; 
 

 
var withinTagsAndQuotes = [].concat.apply([], // flattens the following 
 
    matchAll(withinTagsRegexp, SAMPLE_STRING).map(
 
    matchAll.bind(undefined, withinQuotesRegexp))); 
 

 
// show the result 
 

 
var resultTag = document.getElementById('result'); 
 

 
withinTagsAndQuotes.forEach(function(entry) { 
 
    var p = document.createElement('p'); 
 
    p.innerHTML = entry; 
 
    resultTag.appendChild(p); 
 
});
<div id="result"></div>

+1

Aspetta, come sei riuscito a renderlo così lungo: P – nicael