Нужно регулярное выражение для соответствия первому вхождению символа в строке

У меня есть sql-запрос в виде строки, и мне нужно регулярное выражение для соответствия первому вопросительному знаку (?) В строке

select * from something where a = ? and b=? and c=?

Регулярное выражение должно соответствовать только первому вхождению вопросительного знака. Я буду использовать это регулярное выражение в библиотеке Neo4j-apoc (apoc.text. заменить функцию). В отличие от Perl/Java и т. д., эта библиотека не предоставляет никакого флага или API для получения первого совпадения. Поэтому я должен полностью полагаться на регулярное выражение, чтобы соответствовать только первому символу.

Я пробовал некоторые из приведенных ниже регулярных выражений, но не повезло

Эти регулярные выражения ничего не соответствуют

(?<=^[^?]{0,1000})[?]

Эти регулярные выражения соответствуют всем несуществующим символам и всем вопросительным знакам.

[?]?
([?])?
([\?])?
([\?])??
([?])*?

Эти регулярные выражения соответствуют всем вопросительным знакам

([?])+?
[?]+?

Может ли кто-нибудь помочь мне написать это регулярное выражение?


person Fayaz    schedule 22.02.2018    source источник
comment
Всегда ли 3 вопросительных знака? Если нет, будет ли работать регулярное выражение, которое фиксирует первый ? как группу 1?   -  person Bohemian♦    schedule 22.02.2018
comment
Вы имеете в виду это   -  person Mohammad Javad Noori    schedule 22.02.2018
comment
@Bohemian, приведенный выше запрос является всего лишь образцом, вопросительных знаков не может быть ни одного, ни n. Мне нужно соответствовать только первому. Я не могу использовать группу в библиотеке neo4j-apoc. Мне нужно регулярное выражение, которое однозначно соответствует только первому?.   -  person Fayaz    schedule 22.02.2018


Ответы (4)


Что ж, я придумал странное решение, но, может быть, вы возьмете такое:
(?<!\?)\?{1}(?!.*?\?)|(?<=\?)\?{1}(?!.*?\?)
будет соответствовать только последнему ?.
Итак, хотя вы не можете напрямую узнать первое, вы можете обратить свою строку, а затем найти последнее.
Я использовал Regex101 для проверки.

[ОБНОВЛЕНИЕ]:
он находит последнее вхождение ? перед \n.

person Leonardo Maffei    schedule 22.02.2018
comment
Выглядит полезно, я попробую и посмотрю, смогу ли я использовать это. Спасибо - person Fayaz; 22.02.2018
comment
@Фаяз, пожалуйста. И спасибо за вопрос, было очень интересно об этом подумать. - person Leonardo Maffei; 22.02.2018

вы можете использовать ([^?]+)(\?)(.+)

и вы можете получить первый вопросительный знак с помощью $2

Онлайн-демонстрация

person Mohammad Javad Noori    schedule 22.02.2018
comment
Это регулярное выражение соответствует всей строке вместе с первым вопросительным знаком. Когда я использую это в neo4j-apoc (функция apoc.text.replace), она заменяет всю строку. Мне нужно сопоставить только первый вопросительный знак, а не другую часть строки. - person Fayaz; 22.02.2018

Вы не можете использовать lookbehind с квантификатором, таким как (?<=^[^?]{0,1000}).

В таком случае (по крайней мере, в regex101.com) вы получите сообщение об ошибке: {0,1000} A quantifier inside a lookbehind makes it non-fixed width.

Чтобы соответствовать первому ?, вы можете использовать ^[^?]*(\?), что означает:

  • ^ — начало строки.
  • [^?]* - (возможно, пустая) последовательность символов, отличных от ?.
  • (\?) - Персонаж, которого вы хотите захватить.

Первый ? будет содержимым первой группы захвата.

Редактировать

Другое решение, возможное, если вы используете PCRE версию регулярного выражения:

^[^?]*\K\?

имея в виду:

  • ^[^?]* — соответствует «начальной» последовательности символов, кроме ?.
  • \K — «Забудьте» о том, что вы сопоставили до сих пор, и начните сопоставлять отсюда.
  • \? — Соответствие ?.

Таким образом, ваше полное совпадение будет первым ? без каких-либо захваченных групп.

person Valdi_Bo    schedule 22.02.2018

Если ваш механизм регулярных выражений поддерживает положительный просмотр назад (?<, вы можете выбрать только первый вопросительный знак. использовать:

(?<=where a = )\? или без (?<=a = )\?

person The fourth bird    schedule 22.02.2018