RegEx-golf: сопоставить все содержимое в строке

10

Ваша задача - написать RegEx, который соответствует всему в строках.

Строка определяется как все, что окружено (но не включает) двумя неэкранированными ".

A "может быть экранирован \, что также может быть экранировано снова.

Testcases

string:  ab\c"defg\\\"hi"jkl"mn\\\\"opqrst""
matches:      ^^^^^^^^^^     ^^^^^^        ^ (the empty string)

счет

Самое короткое решение побеждает.

Спекуляции

  • Пожалуйста, укажите используемый аромат.
  • Вход будет сбалансированным ".
  • Там не будет, \что непосредственно предшествует начало строки-разделитель. Например, вам не нужно обрабатыватьabc\"def"
Дрянная Монахиня
источник
1
Будет ли \перед строкой? Например abc\"def".
jimmy23013
Должно ли оно соответствовать каждой строке в одной группе? Например, могу ли я написать что-то, что имеет два совпадения abc"de", одно есть, dа другое есть e?
jimmy23013
Это разрешено
Утренняя монахиня
Будут ли пустые строки?
Мартин Эндер
Да, там будут пустые строки.
Дрянная Монахиня

Ответы:

3

PCRE, 21 20 15 19 байт

(.|^)"\K(\\.|[^"])*

Попробуй это здесь.

Это соответствует символу (или началу ввода) перед началом двойной кавычки, а затем сбрасывает совпадение, чтобы убедиться, что двойная кавычка не передана другому совпадению.

PCRE, 25 23 байта

Спасибо Мартину Бюттнеру за то, что он сыграл в гольф 2 байта.

(\\.|[^"])*+(?!"(?R)|$)

Попробуй это здесь.

объяснение

(
    \\.|[^"]     # An escaped character, or a character that isn't a double quote
)*+              # Possessive zero-or-more quantifier, which means backtracking
                 # could not happen after first match is found. That means if \\.
                 # matched, it would never switch to [^"], because it is always a
                 # match if it just stopped after the \\. without backtracking.
(?!"(?R)|$)      # Make sure it is not followed by a double quote and another
                 # match, or the end of the input.

Обратите внимание, что притяжательный quantifier ( *+) следит за тем, чтобы отрицательный прогноз всегда начинался после всей строки или целого сегмента, не являющегося строкой.

Есть 4 случая:

  • Матч начинается за пределами строки. \\.никогда не будет соответствовать двойной кавычке в соответствии с разъяснениями. Он может закончиться только перед следующей двойной кавычкой, которая начинает строку или конец ввода. Оба случая терпят неудачу в негативной перспективе.
  • Матч начинается в начале строки. (\\.|[^"])*+будет соответствовать полной строке. Следующий символ должен быть в двойной кавычке и не может быть концом ввода. После двойной кавычки он находится за пределами строки, поэтому он не может быть другим совпадением. Таким образом, он проходит негативную перспективу.
  • Матч начинается в конце строки. Он соответствует пустой строке так же, как и в предыдущем случае. Но это не имеет значения согласно разъяснениям.
  • Матч начинается в середине строки. Невозможно, потому что спички не перекрываются.
jimmy23013
источник
Будет (\\.|[^"])работать?
Мартин Эндер
@ MartinBüttner, который соответствует всему, кроме "
Bálint
@ Bálint Я имел в виду вместо ([^\\"]|\\.), а не как полное решение.
Мартин Эндер
@ MartinBüttner О, хорошо
Балинт
Предложение Мартина должно сработать, поскольку происходит \\.сбой только в том случае, если после него нет символа \(или символа новой строки, но это можно исправить с помощью флага), и этот случай покрывается отрицательным искомым следом. Собственный квантификатор предотвращает возврат, поэтому у нас нет другого случая, чтобы посмотреть.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
0

JavaScript, 24 байта

"([^"\\]*(?:\\.[^"\\]*)*)"

Группа 1 - это содержимое строки.

Whothehellisthat
источник
Это совсем не работает с экранированными кавычками и, следовательно, не соответствует спецификации.
ATaco
Ах да, извините. Как насчет этого?
Кто сказал, что
Близко, но без сигары, вы не должны соответствовать внешнему "s
ATaco
Да, это то, чего я боялся. Наверное, нет способа сделать это на JavaScript?
Кто сказал, что
Вы можете захватить его в подгруппе
ATaco
0

JavaScript, 21 15 13 12 байт

"((\\?.)*?)"

Содержимое строки в группе 1.

"   #start of string
(    #capturing group
 (
  \\?. #match character or escaped character
 )*?  #match as few as possible
)        
"   #end of string
12Me21
источник