2013-10-01 3 views
3

Я ищу регулярное выражение, чтобы соответствовать только строкам MBCS внутри проекта C++. Это строки, содержащиеся в двойных кавычках без спецификатора L"..." или _T("..."). В любой строке кода может быть несколько котировок. Строки могут содержать экранированные подстроки, которые не должны заканчивать совпадение. Вот несколько примеров:Regex, чтобы соответствовать нескольким строкам MBCS в любой строке

"This is a MBCS string"; // "This is a MBCS string" match 
_T("This is maybe a unicode string"); // no match 
L"This is a unicode string"; // no match 
"These both" + "should match"; // "These both" and "should match" match 
"This is a \"quoted\" string"; // "This is a \"quoted\" string" match 

У меня есть регулярное выражение, чем может обрабатывать все этот штраф с использованием отрицательного lookbacks (?<!#include)(?<!_T\()(?<!\\)(?<!L)\"(.*?)\"(?<!\\\"), но она становится все более сложной, все же. У него возникают проблемы с перемещением типов строк на одной строке.

_T("Maybe this") + "is a match"; // "is this" match but instead would match ") + " 
do_something(_T("This doesn't match")) + do_something("but this does match"); // "but this does match" match but instead it matches ")) + do_something(" 

Как я могу иметь регулярное выражение не совпадают по _T("") и L"" слов, но по-прежнему соответствовать им есть конец цитаты без возвращения его в матче?

Редактировать: Это регулярное выражение, (?:_T\(\"[^\"]+\"\).*?|L\"[^\"]+\".*?)*(?<!#include)(?<!_T\()(?<!L)(?<!\\)\"(.*?)\"(?<!\\\"), почти выполняет эту работу, но есть еще один тестовый пример, который не срабатывает, и я не думал, что его первоначально включить.

_T("don't match this") + _T("or this"); // shouldn't match anything, matches ") + _T(" 
+0

Не можете вы подходите все из них, а затем отфильтровать те, которые начинаются с 'L' или' _T (' – Bergi

+0

Если ваши строки хорошо сформированы, я бы извлечь каждый' (?: L | _T \ s * \ (\ s *)? "(?: [^ \"] + | \\ ") *" "и затем проверить, имеет ли префикс перед открывающей цитатой. – tripleee

+0

Да, это определенно Я думал, был ли простой способ придумать правильное регулярное выражение, но это выглядит сложнее и труднее, поскольку я запускаю его через некоторые реальные файлы. – Kyle

ответ

2

Вы могли бы фактически соответствовать _T и L части так, что они потребляются в предыдущем матче:

(?:_T\(\"[^\"]+\"\).*?|L\"[^\"]+\".*?)?(?<!#include)(?<!_T\(|L|\\)\"(.*?)\"(?<!\\\") 

Я также сократил отрицательный просмотр назад.

regex101 demo

+0

Это работает, спасибо! Чтобы использовать его с Python I пришлось расширять укороченный взгляд позади, он работает только по фиксированной длине, поэтому я получил следующее: (?: _ T \ (\ "[^ \"] + \ "\). *? | L \" [^ \ "] + \". *?)? (? Kyle

+0

@Kyle О, ладно, понятно, это значит, что вы все равно сможете использовать '(? Jerry

+0

Это хорошее решение проблемы, которую я предложил, но я пропустил большой тестовый пример в моем первоначальном примере с двумя экранированными строками '_T (« test »), _T (« case »)'. Он не соответствует группе без захвата и попадает между двумя строками с символом '), _T (' что неверно. Можно зафиксировать нулевые символы или основной захват, насколько я могу судить, но это нарушает подстановку Python на не записывая ничего в большинстве строк и бросая исключение. Лучше всего всего захватить любую строку @tripleee и проверить внешность на регулярное выражение, если это строка MBCS. – Kyle

Смежные вопросы