Предположим, у меня была следующая строка, в которой я хотел запустить регулярное выражение:
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.
Теперь предположим, что я хотел заменить все символы между кавычками , скажем, пробелом. Я думал, что могу сделать это с помощью регулярного выражения, выглядящего следующим образом:
Find What: (\"[^"]*?)(\-)([^"]*?\") Replace With: $1 $3
Проблема, с которой я сталкиваюсь, заключается в том, что с использованием этого шаблона он не учитывает, открывал ли кавычек или закрывал оператор.
Таким образом, в приведенном выше примере символ в per-se
будет заменен пробелом, так как он находится между двумя кавычками, но между закрывающей и открывающейся меткой. Когда я специально хочу посмотреть текст между открытием и знак закрытия .
Как вы объясняете это в таком регулярном выражении?
Я надеюсь это имеет смысл.
Я использую VB / C # Regex.
Чтобы закончить вопрос (и, надеюсь, при необходимости еще немного уточнить), конечным результатом, который я бы хотел получить, было бы:
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.
Спасибо!!
Выдохнул мой мозг, чтобы работать над этим, оказывается, что указание границ без слов \B
делает трюк:
\B("[^"]*)-([^"]*")\B
$1 $2
У вас такая же проблема, как и у кого-то, кто пытается сопоставить HTML-код или открывать и закрывать круглые скобки, регулярное выражение может соответствовать только обычным языкам и знать, что "
является закрывающим, а открывающее не доступно для чего-либо, кроме тривиальных случаев.
EDIT: Как показано в ответе Василия Сиракиса, иногда это можно сделать, но регулярное выражение является хрупким решением для такого типа проблем.
С учетом сказанного вы можете преобразовать свою проблему в тривиальный случай. Поскольку вы используете .NET, вы можете просто сопоставить каждую строку с кавычками и использовать перегрузку, которая принимает оценку соответствия .
Regex.Replace(text, "\".*?\"", m => m.Value.Replace("-", " "))
Тестовое задание:
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.
Вместо регулярного выражения обычный метод для этого может быть более удобным для обслуживания в долгосрочной перспективе:
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(); }
Затем, чтобы использовать его:
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(" "));
Я разделил бы строку на массив строк, используя кавычку «как разделитель». Тогда все строки с индексом нечетного числа будут строкой в паре кавычек, используйте ваше регулярное выражение только для aSplittedString [oddIndex], затем соедините весь массив с помощью “.
То, что вам нужно сделать, явно соответствует только строкам внутри кавычек, которые имеют .
Использовать этот:
(\"[^"]*.*?)-(.*?\")
Рабочий пример: http://regex101.com/r/jK5eL9
Единственный улов в том, что он будет работать только для отдельных word-word
в кавычках. Если бы у вас было, скажем, "word-word, and word-word"
это не получится.