Ответ 1
Как насчет этого?
/"([^\\"]|\\\\|\\")*"/
соответствует нулю или нескольким символам, которые не являются косой чертой или кавычками ИЛИ двумя косой чертой ИЛИ косой чертой, а затем цитатой
Мне нужно регулярное выражение Perl для соответствия строке. Я предполагаю только строки с двойными кавычками, что a\является литеральным символом кавычки, а НЕ конец строки и что a - буквальный символ обратной косой черты и не должен пропускать символ цитаты. Если это не ясно, некоторые примеры:
"\"" # string is 1 character long, contains dobule quote
"\\" # string is 1 character long, contains backslash
"\\\"" # string is 2 characters long, contains backslash and double quote
"\\\\" # string is 2 characters long, contains two backslashes
Мне нужно регулярное выражение, которое может распознать все 4 из этих возможностей и все другие простые варианты этих возможностей, как правильные строки. Теперь у меня есть:
/".*[^\\]"/
Но это не так - оно не будет соответствовать ни одному из них, кроме первого. Может ли кто-нибудь дать мне толчок в правильном направлении о том, как с этим справиться?
Как насчет этого?
/"([^\\"]|\\\\|\\")*"/
соответствует нулю или нескольким символам, которые не являются косой чертой или кавычками ИЛИ двумя косой чертой ИЛИ косой чертой, а затем цитатой
/"(?:[^\\"]|\\.)*"/
Это почти то же самое, что и ответ Cal, но имеет преимущество в сопоставлении строк, содержащих escape-коды, такие как \n
.
Символы ?:
предназначены для предотвращения сохранения содержащегося выражения в качестве обратной ссылки, но их можно удалить.
Общее решение (сопоставление всех символов с обратной косой чертой):
/ \A " # Start of string and opening quote
(?: # Start group
[^\\"] # Anything but a backslash or a quote
| # or
\\. # Backslash and anything
)* # End of group
" \z # Closing quote and end of string
/xms
См. Текст:: Сбалансированный. Это лучше, чем изобретать велосипед. Используйте gen_delimited_pat
, чтобы увидеть шаблон результата и изучить его форму.
RegExp::Common - еще один полезный инструмент, о котором нужно знать. Он содержит регулярные выражения для многих распространенных случаев, включая цитированные строки:
use Regexp::Common;
my $str = '" this is a \" quoted string"';
if ($str =~ $RE{quoted}) {
# do something
}
Здесь очень простой способ:
/"(?:\\?.)*?"/
Просто помните, если вы встраиваете такое регулярное выражение в строку, чтобы удвоить обратную косую черту.
Попробуйте этот фрагмент кода: (\".+")