Regex – Voglio solo abbinare i tag di inizio in regex

Sto facendo un’espressione regolare in cui voglio solo abbinare tag errati come:

*some text here, some other tags may be here as well but no ending 'p' tag*

  

Affectionately Inscribed

TO

HENRY BULLAR,

(of the western circuit)

PREFACE

Nello stesso testo sopra voglio ottenere il risultato come

(of the western circuit)

e nient’altro dovrebbe essere catturato. Sto usando questo, ma non funziona:

 

[^\(

\)]*

Per favore aiuto.

Solutions Collecting From Web of "Regex – Voglio solo abbinare i tag di inizio in regex"

Regex non è sempre una buona scelta per i dati di tipo xml / html. In particolare, gli attributi, la distinzione tra maiuscole e minuscole, i commenti, ecc. Hanno un grande impatto.

Per xhtml, XmlDocument / XDocument e una query xpath.

Per l’html “non-x”, guarderei l’ HTML Agility Pack e lo stesso.

Abbina il gruppo uno di:

 (?:

(?:(?!< \/?p>).?)+)(

)

corrisponde al secondo

in:

 

(of the western circuit)

PREFACE

Nota: di solito sono uno di quelli che dice: “Non fare HTML con regex, usa invece un parser”. Ma non penso che il problema specifico possa essere risolto con un parser, che probabilmente ignorerebbe / tratterebbe in modo trasparente il markup non valido.

So che questo non è probabile (o anche html-legale?) Per accadere in questo caso, ma una soluzione generica di tag xml non chiusa sarebbe piuttosto difficile in quanto è necessario considerare cosa accadrebbe con tag nidificati come

 

OUTER BEFORE

INNER

OUTER AFTER

Sono abbastanza sicuro che le espressioni regolari date così lontano corrispondano al secondo

, anche se in realtà non è un

non chiuso.

Piuttosto che usare * per la corrispondenza massima, usare *? per il minimo

Dovrebbe essere in grado di iniziare

 

((?!

).)*?

Questo utilizza un’asserzione lookahead negativa per garantire che il tag di fine non sia abbinato in ogni punto tra le corrispondenze ”

“.

EDIT: corretto per mettere l’asserzione (grazie al commentatore).

Tutte le soluzioni offerte finora corrispondono al secondo

, ma è sbagliato. Cosa succede se ci sono due elementi

consecutivi senza tag di chiusura? Il secondo non sarà abbinato perché la prima partita ha mangiato il suo tag di apertura. Puoi evitare questo problema usando un lookahead come ho fatto qui:

 @"

(?:[^< ]+|<(?!/?p>))*)(?=

Per quanto riguarda il resto, ho usato una tecnica "non quella iniziale o no" insieme a un gruppo atomico per guidare la regex a una partita nel modo più efficiente ansible (e, cosa più importante, per fallire il più rapidamente ansible se è andando a).