Регулярное выражение для поиска групп совпадений для 1 обратной и 3 обратной кавычек

Я пытаюсь создать регулярное выражение, которое соответствует внутренней стороне обратной кавычки, 1 или 3.

У меня есть следующее регулярное выражение, которое работает для 1 обратной кавычки:

`(.*?)`

и этот работает с 3:

```(.*?)```

Я хочу объединить их в один поиск по регулярному выражению, я пробовал что-то вроде

(`|```)(.*?)(`|```)

Но это создает слишком много групп совпадений, я пробовал $ и ^, но это похоже на начало строки и конец строки ...

Пограничный случай 1:

My SQL Statement is below:
```
SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";
```

должна иметь 1 группу с:

SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";

Пограничный случай 2

My SQL Statement is below:
```
SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";
```

```
SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 2";
```

Должно быть 2 группы:

SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";

а также

SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 2";

Пограничный случай 3

My SQL Statement is below:
```
SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";
SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 2";
```

Должна быть 1 группа:

SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";
SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 2";

Следует поместить весь блок в группу


Крайний случай 4

SQL_STATEMENT = "SELECT * FROM `table` WHERE `id` = 1";

Должно быть 2 группы

table

а также

id

person Arian Faurtosh    schedule 01.05.2020    source источник
comment
Вы можете использовать (?<!`)```(?!`)(.+?)(?<!`)```(?!`) (с установленным флагом однострочного режима /s) для пограничного случая, но это не работает для других ваших примеров. Демо.   -  person Cary Swoveland    schedule 01.05.2020
comment
@CarySwoveland, можете ли вы написать это как ответ, его трудно увидеть в строке, и я думаю, что обратные кавычки в решении анализируются   -  person Arian Faurtosh    schedule 01.05.2020
comment
Теперь это нормально? Я избежал обратных кавычек, чтобы их можно было увидеть. Конечно, вы также можете увидеть это по ссылке au naturel.   -  person Cary Swoveland    schedule 01.05.2020
comment
@CarySwovel, и это решение не обнаруживает однострочные обратные кавычки, такие как `2343245`   -  person Arian Faurtosh    schedule 01.05.2020
comment
Да, я это сказал. Он просто захватывает все, что находится между парами тройных обратных кавычек, обратных кавычек и всего остального. Это просто для вашего примера крайнего случая.   -  person Cary Swoveland    schedule 01.05.2020
comment
Ах да, ты сделал   -  person Arian Faurtosh    schedule 01.05.2020
comment
(?<!`)```(?!`)(.+?)(?<!`)(?=```(?!`))```|(?<!`)`(?!`)(.+?)(?<!`)(?=`(?!`)) работает со всеми четырьмя крайними случаями, а также с другими демонстрацией. Мне пришлось сначала показать крайние случаи по ссылке, потому что они не подходят для моих примеров несоответствий. Например, если бы у меня было `ab`` до того, как крайние случаи `ab` завершились неудачно, тогда он сопоставлял бы второй обратный апостроф и поглощал символы, включая символы новой строки и тройные обратные кавычки, пока не нашел бы одиночный обратный апостроф, который был бы посередине вашего первого края. кейс...   -  person Cary Swoveland    schedule 01.05.2020


Ответы (2)


Захватите либо 1 , либо 3 обратных кавычки и используйте обратную ссылку в конце, чтобы они были сбалансированы.

Простая версия:

(`(?:``)?)([^`]+)\1

Только версия Balaced. (т.е. количество обратных кавычек одинаково в начале и в конце)

(?<=[^`]|^)(`(?:``)?)([^`]+)\1(?=[^`]|$)

Ваша цель (содержание) находится в группе 2

См. живую демонстрацию.

person Bohemian♦    schedule 01.05.2020
comment
Спасибо! Это работает для меня ... единственная проблема в том, что я думаю, что если вы вкладываете 1 галочку в 3 галочки, он предпочитает внутреннее гнездо, не имеет большого значения, просто крайний случай - person Arian Faurtosh; 01.05.2020
comment
Посмотрите, подходит ли вам последняя версия. Если нет, опубликуйте, пожалуйста, свой крайний чехол. - person Bohemian♦; 01.05.2020
comment
Опубликовать новый вопрос или изменить мой текущий? - person Arian Faurtosh; 01.05.2020
comment
Изменить текущий. Подозреваю, что ваш крайний случай - разумная вещь, с которой работает это регулярное выражение. - person Bohemian♦; 01.05.2020
comment
Да, добавлено к исходному вопросу - person Arian Faurtosh; 01.05.2020
comment
Хорошее решение. Рассмотрите возможность замены просмотра назад на (?<!`) и просмотра вперед на (?!`). Он короче, и я бы сказал, что он читается лучше. Я вижу, что вы тестировали Rubular, но не часто встречаете там ruby теги. - person Cary Swoveland; 01.05.2020
comment
@Cary Я использую rubular, потому что это единственный тестер регулярных выражений, который, как я обнаружил, работает при просмотре на моем iPhone. Остальные более красивы, но требуют мыши, иначе они совершенно непригодны для использования. Мне также нравится его простая постоянная ссылка. Что касается предложения, я подумаю! - person Bohemian♦; 01.05.2020
comment
@ArianFaurtosh относительно вашего нового пограничного случая, есть ли когда-нибудь несколько экземпляров примера SQL на одном входе? - person Bohemian♦; 01.05.2020
comment
Обратите внимание, что ``ab`, `ab`` и ````ab``` все совпадают в простом случае, потому что ничто не препятствует появлению дополнительных обратных кавычек на обоих концах. - person Cary Swoveland; 01.05.2020
comment
@Bohemian это больше похоже на то, что кто-то может захотеть обернуть оператор SQL в 3 обратных кавычки, но сам оператор SQL может содержать одиночные обратные кавычки - person Arian Faurtosh; 01.05.2020
comment
@ArianFaurtosh, но это критически важно для решения: может ли быть несколько операторов SQL (которые могут содержать обратные кавычки) на одном входе? Да или нет? - person Bohemian♦; 01.05.2020
comment
@Bohemian Может быть несколько операторов SQL, но это должно быть нормально, поскольку все они будут содержать только обратные кавычки. Я добавлю несколько дополнительных примеров к вопросу выше - person Arian Faurtosh; 01.05.2020

Вот несколько способов сделать это.

Соответствующие строки

(?<=(?<!`)`)[^`\r\n]+(?=`(?!`))|(?<=(?<!`)```)[^`\r\n]+(?=```(?!`))

Обратите внимание, что это регулярное выражение не имеет групп захвата.

Демонстрация PCRE (PHP)

Механизм регулярных выражений PCRE выполняет следующие операции.

(?<=       begin a positive lookbehind
  (?<!`)   following is not preceded by a backtick
  `        match a backtick
)          end positive lookbehind
[^`\r\n]+  match 1+ chars other than backtick, CR or newline
(?=        begin positive lookahead
  `        match a backtick
  (?!`)    not followed by a backtick
)          end positive lookhead
|
(?<=       begin a positive lookbehind
  (?<!`)   following is not preceded by a backtick
  ```      match 3 backticks
)          end positive lookbehind
[^`\r\n]+  match 1+ chars other than backtick, CR or newline
(?=        begin positive lookahead
  ```      match 3 backticks
  (?!`)    not followed by a backtick
)          end positive lookhead

(?<!...) - это отрицательный взгляд назад; (?!...) - это негативный прогноз.

Используйте группы захвата

(?<!`)`([^`\r\n]+)`(?!`)|(?<!`)```([^`\r\n]+)```(?!`)

Демонстрация PCRE (PHP)

Вы увидите, что это регулярное выражение имеет две группы захвата. Если есть совпадение с одним обратным апострофом, часть между обратными апострофами удерживается в группе захвата 1, а группа захвата 2 не создается, а при совпадении с тремя обратными кавычками часть между тройками обратных апострофов удерживается в группе захвата 2. , а группа захвата 1 не создается.

person Cary Swoveland    schedule 01.05.2020