Мне нужно регулярное выражение, которое соответствует строке, заключенной в двойные кавычки. Он не должен соответствовать строке, заключенной в двойные кавычки, если этот шаблон заключен в одинарные кавычки:
"string"
" 'xyz' "
" `" "
" `" `" "
" `" `" `" "
' ' "should match" ' '
' "should not match" '
Теперь у меня есть (https://regex101.com/r/z5PayV/1)
(?:"(([^"]*`")*[^"]*|[^"]*)")
который соответствует всем строкам. Но последняя строка не должна совпадать. Любое решение?
Что вы имеете в виду под this pattern
? Все ваше текущее регулярное выражение?
@dvo Последние 2 строки не подходят для одной и той же ситуации. Если подумать о сценариях оболочки, таких как bash или powershell, последняя строка представляет одну строку, а вторая последняя строка представляет 3 строки. Ответ показывает, что регулярное выражение может решить эту проблему.
Вы должны пройти мимо одинарных кавычек, чтобы исключить их из совпадения
Обновить
Для C# это нужно сделать так.
Просто использует простой CaptureCollection, чтобы получить все
указанные совпадения.
(?:'[^']*'|(?:"(([^"]*`")*[^"]*|[^"]*)")|[\S\s])+
Расширенный
(?:
' [^']* '
|
(?:
"
( # (1 start)
( [^"]* `" )* # (2)
[^"]*
| [^"]*
) # (1 end)
"
)
|
[\S\s]
)+
код С#
var str =
"The two sentences are 'He said \"Hello there\"' and \"She said 'goodbye' and 'another sentence'\"\n" +
"\" `\" \"\n" +
"\" `\" \"\n" +
"\" `\" `\" \"\n" +
"\" `\" `\" `\" \"\n" +
"' \" \" '\n" +
"\"string\"\n" +
"\" 'xyz' \"\n" +
"\" `\" \"\n" +
"\" `\" `\" \"\n" +
"\" `\" `\" `\" \"\n" +
"' ' \"should match\" ' '\n" +
"' \"should not match\" '\n";
var rx = new Regex( "(?:'[^']*'|(?:\"(([^\"]*`\")*[^\"]*|[^\"]*)\")|[\\S\\s])+" );
Match M = rx.Match( str );
if (M.Success)
{
CaptureCollection cc = M.Groups[1].Captures;
for (int i = 0; i < cc.Count; i++)
Console.WriteLine("{0}", cc[i].Value);
}
Выход
She said 'goodbye' and 'another sentence'
`"
`"
`" `"
`" `" `"
string
'xyz'
`"
`" `"
`" `" `"
should match
Извините, так это делается в движке PCRE.
'[^']*'(*SKIP)(*FAIL)|(?:"(([^"]*`")*[^"]*|[^"]*)")`
https://regex101.com/r/gMiVDU/1
' [^']* '
(*SKIP) (*FAIL)
|
(?:
"
( # (1 start)
( [^"]* `" )* # (2)
[^"]*
| [^"]*
) # (1 end)
"
)
___________________________-
Я принял этот ответ, хотя вторая группа без захвата, я думаю, неверна. Если я удалю его, двойные кавычки тоже будут сопоставлены. @sln не могли бы вы подтвердить это? Спасибо.
@TobiasWollgam - Можете ли вы уточнить, какое регулярное выражение и где, по вашему мнению, возникла проблема? Спасибо.
@@TobiasWollgam — обратите внимание, что в регулярном выражении C# вся строка всегда соответствует одному совпадению. Это по дизайну, это ничего не повредит и не замедлит. Все захваты группы 1 записываются в список. Это похоже на функцию типа findall() на стероидах.
Извините, если я неясен. В вашем выводе мне не хватает начальных и конечных двойных кавычек. Итак, мое решение состояло в том, чтобы удалить вторую незахватывающую группу ?:
, чтобы регулярное выражение стало (?:'[^']*'|("(([^"]*´")*[^"]*|[^"]*)")|[\S\s])+
(заменил исходную обратную кавычку на foretick, потому что обратные кавычки используются для маркировки кода в комментариях). Теперь вывод вашего кода С# содержит двойные кавычки. Поскольку я не тестировал его с моим производственным кодом, где объект Regex передается коду соответствия С#, полученному от третьей стороны, я не знаю, работает ли одно из регулярных выражений.
@TobiasWollgam - понятно. Конечно, вы также можете использовать группы захвата вокруг кавычек, если хотите их увидеть. На самом деле, все группы поддерживают отдельную коллекцию захвата (список), которую вы можете перебирать после совпадения. Пример: CaptureCollection cc1 = M.Groups[1].Captures; CaptureCollection cc2 = M.Groups[2].Captures; CaptureCollection cc3 = M.Groups[3].Captures;
и т.д...
Ответ выглядит довольно сложным, как это:
^"(\d+|\D+)"$
это слишком просто?
Идея здесь состоит в том, чтобы проверить, что строка начинается и заканчивается двойной кавычкой ("), все, что находится внутри двойной кавычки, включая одинарную кавычку, разрешено.
Пожалуйста, уточните также
Добро пожаловать в Stack Overflow! Вы сравнивали свое решение с приведенными примерами?
Разве последние 2 строки не соответствуют одной и той же ситуации в этом отношении: строка, заключенная в двойные кавычки, также заключенная в одинарные кавычки? Почему должно предпоследнее совпадение, а не самое последнее?