C ++ регулярное выражение для правильного соответствия строк, которые содержат escape-символы в стиле c (стиль ECMAScript, без просмотра) - PullRequest
0 голосов
/ 23 января 2020

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

Другими словами, мне нужно регулярное выражение, которое между двумя вопросами маркирует, будет соответствовать всем символам, которые не являются кавычками, а также любым кавычкам, которые имеют нечетное число последовательных обратных косых черт, предшествующих ему. Это должно быть нечетное количество обратных косых черт, поскольку пара обратных косых черт убегает в одну обратную косую черту sh.

Я успешно создал регулярное выражение, которое делает это, но оно полагалось на предварительную проверку и потому, что этот проект находится в C ++, и поскольку реализация стандартного C ++ для регулярных выражений не имеет функциональности поиска, я не смог использовать упомянутое регулярное выражение.

Вот регулярное выражение с поисковым запросом, которое я придумал: "(((?<!\\)(\\\\)*\\"|[^"])*)"

В следующем тексте должно быть 8 совпадений:

"Woah. Look. A  tab."
"This \\\\\\\\\\\\\" is all one string"
"This \"\"\"\" is\" also\"\\ \' one\"\\\" string."
"These \\""are separate strings"
"The cat said,\"Yo.\""
"
\"Shouldn't it work on multiple lines?\" he asked rhetorically.
\"Of course it should.\"
"
"If you don't have exactly 8 matches, then you've failed."

Вот изображение моей (вероятно, наивной) альтернативной версии для визуальных людей из вас (вы знаете, кто вы): enter image description here

И вот ссылка на этот пример: https://regex101.com/r/uOxqWl/1

Если это невозможно сделать без предварительного просмотра, пожалуйста, дайте я знаю. Кроме того, если есть уважаемая библиотека регулярных выражений C ++, которая позволяет просматривать регулярные выражения, пожалуйста, дайте мне знать (это не обязательно должен быть ECMAScript, хотя я бы немного предпочел это).

1 Ответ

0 голосов
/ 23 января 2020

Давайте выведем регулярное выражение сорта для сада для C -стилей строки из описания Engli sh.

Строка - это кавычка, за которой следует последовательность строки -символы , за которыми следует еще одна кавычка.

std::regex stringMatcher ( R"("<string-character>*")" );

Очевидно, это не сработает, поскольку мы еще не определили строковый символ . Мы можем сделать это по частям.

Во-первых, строковым символом может быть любой символ, кроме кавычки и обратного знака sh.

 R"([^\\"])"

Во-вторых, строковый символ может быть escape-последовательность, состоящая из backsla sh и одного другого символа из фиксированного набора.

 R"(\\[abfnrtv'"\\?])"

В-третьих, это может быть восьмеричная восьмеричная последовательность, состоящая из backsla sh и трех восьмеричных цифр

 R"(\\[0-7][0-7][0-7])"

(Здесь мы немного упрощаем, потому что действительный стандарт C допускает 1, 2 или 3 восьмеричные цифры. Это легко добавить.)

В-четвертых, это может быть шестнадцатеричная escape-последовательность, состоящая из обратного знака sh, буквы x и шестнадцатеричного числа. Диапазон числа определяется реализацией, поэтому мы должны принять любое.

 R"(\\x[0-9a-fA-F][0-9a-fA-F]*)"

Мы опускаем универсальные имена символов, они могут быть добавлены точно таким же образом. В данном тестовом примере их нет.

Итак, чтобы собрать все это вместе:

 std::regex stringMatcher ( R"("([^\\"]|\\([abfnrtv'"\\?]|[0-7][0-7][0-7]|x[0-9a-fA-F][0-9a-fA-F]*))*")" ); 
// collapsed the leading backslashes of all the escape sequence types together

Live demo .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...