Schema Regex per scegliere i dati TRA le virgolette corrispondenti

Supponiamo di avere la seguente stringa che volevo eseguire un’espressione regolare su:

This is a test string with "quotation-marks" within it. The "problem" I am having, per-se, is "knowing" which "quotation-marks" go with which words. 

Ora, supponiamo di voler sostituire tutti i - caratteri tra le virgolette con, diciamo, uno spazio. Stavo pensando che potrei farlo con una regex come segue:

 Find What: (\"[^"]*?)(\-)([^"]*?\") Replace With: $1 $3 

Il problema che sto avendo è che usando questo modello, non tiene conto dell’apertura o della chiusura dell’istruzione di una virgoletta.

Quindi, nell’esempio sopra, il carattere - in per-se sarà sostituito da uno spazio poiché è tra 2 virgolette, ma tra un segno di chiusura e un segno di apertura – Quando voglio specificamente guardare all’interno del testo tra un’apertura e un segno di chiusura .

Come spiegate questo in un’espressione così regolare?

Spero che abbia senso.

Sto usando VB / C # Regex.


Solo per completare la domanda (e se necessario, se necessario, elaborare un po ‘di più), il risultato finale che vorrei ottenere sarebbe:

 This is a test string with "quotation marks" within it. The "problem" I am having, per-se, is "knowing" which "quotation marks" go with which words. 

Grazie!!

Distrutto il mio cervello per risolvere questo problema, risulta che specificare i limiti di non-parola \B fa il trucco:

regex

\B("[^"]*)-([^"]*")\B

Sostituzione

$1 $2


dimostrazione

http://regex101.com/r/dS0bH8

Stai riscontrando lo stesso problema di qualcuno che sta tentando di associare HTML o aprire e chiudere le parentesi, l’espressione regolare può corrispondere solo alle lingue regolari e sapere quale " è una chiusura e una apertura è fuori dalla sua portata per qualsiasi cosa tranne i casi banali.

EDIT: Come mostrato nella risposta di Vasili Syrakis, a volte può essere fatto, ma regex è una soluzione fragile per questo tipo di problema.

Detto questo, puoi convertire il tuo problema nel caso banale. Dato che stai usando .NET, puoi semplicemente abbinare ogni stringa quotata e usare il sovraccarico che richiede un valutatore di corrispondenza .

 Regex.Replace(text, "\".*?\"", m => m.Value.Replace("-", " ")) 

Test:

 var text = @"This is a test string with ""quotation-marks"" within it. The ""problem"" I am having, per-se, is ""knowing"" which ""quotation-marks"" go with which words."; Console.Write(Regex.Replace(text, "\".*?\"", m => m.Value.Replace("-", " "))); //This is a test string with "quotation marks" within it. //The "problem" I am having, per-se, is "knowing" which "quotation marks" //go with which words. 

Invece di una regex, un metodo regolare per farlo potrebbe essere più gestibile a lungo termine:

 public static String replaceDashInQuotes(this string source, String newValue) { StringBuilder sb = new StringBuilder(); bool inquote = false; for (int i = 0; i < source.Length; i++) { if (source[i] == '\"') inquote = !inquote; if (source[i] == '-' && inquote) sb.Append(newValue); else sb.Append(source[i]); } return sb.ToString(); } 

Quindi per usarlo:

 var s = @"This is a test string with ""quotation-marks"" within it. The ""problem"" I am having, per-se, is ""knowing"" which ""quotation-marks"" go with which words."; MessageBox.Show(s.replaceDashInQuotes(" ")); 

Dividerò la stringa in una matrice di stringhe, usando il segno di virgolette “come delimitatore. Quindi tutte le stringhe con un indice di numero dispari saranno la stringa all’interno di una coppia di virgolette, usare solo la regex su aSplittedString [oddIndex], quindi unisciti all’intero array con “.

Quello che devi fare è esplicitamente associare solo stringhe all’interno di virgolette che hanno - .

Usa questo:

 (\"[^"]*.*?)-(.*?\") 

Esempio di lavoro: http://regex101.com/r/jK5eL9

L’unica presa qui è che funzionerà solo per singole istanze di word-word tra virgolette. Se tu avessi, diciamo, "word-word, and word-word" fallirà.