2008-10-30 6 views
81

Как получить подстроку " It's big \"problem " с использованием регулярного выражения?Regex для строки с кавычками с кавычками

s = ' function(){ return " It\'s big \"problem "; }';  
+1

Как найти «это» в строке, которая содержит только «есть»? Я исправлю это для вас, но я не знаю, какие соглашения о одиночной кавычке/побеге применяются на используемом вами языке. – 2008-11-01 15:36:31

+0

Дубликат: [PHP: регулярное выражение, чтобы игнорировать скрытые кавычки в кавычках] (http://stackoverflow.com/q/5695240) – ridgerunner 2011-10-08 14:03:40

+2

Собственно, глядя на даты, я вижу, что другой вопрос является дубликатом этого. В любом случае, обязательно проверьте [мой ответ] (http://stackoverflow.com/questions/5695240/php-regex-to-ignore-escaped-quotes-within-quotes/5696141#5696141). – ridgerunner 2011-10-08 14:20:45

ответ

3
/(["\']).*?(?<!\\)(\\\\)*\1/is 

должен работать с любой строкой в ​​кавычках

+1

Приятный, но слишком гибкий для запроса (будет соответствовать одинарные кавычки ...). И может быть упрощено до /".*?(? PhiLho 2008-10-30 12:47:27

+1

@PhiLho, просто используя одиночный (? 2008-11-01 08:57:33

0

Один должен помнить, что регэкспы не серебряная пуля для всего шнуровки у. Некоторые вещи проще сделать с помощью курсора и линейного, ручного поиска. A CFL сделал бы трюк довольно тривиально, но не так много реализаций CFL (afaik).

+3

Достаточно, но эта проблема хорошо входит в возможности регулярных выражений, и их очень много. – 2008-10-30 16:45:48

103
/"(?:[^"\\]|\\.)*"/ 

Работает в Regex Coach и PCRE Workbench.

Пример теста в JavaScript:

var s = ' function(){ return " Is big \\"problem\\", \\no? "; }'; 
 
    var m = s.match(/"(?:[^"\\]|\\.)*"/); 
 
    if (m != null) 
 
     alert(m);

+0

Работает как шарм – MaX 2012-07-31 13:21:16

23

Это приходит из nanorc.sample доступен во многих дистрибутивах Линукс. Он используется для подсветки синтаксиса строк в стиле C

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

чередуя \" и . проходит через кавычки экранированы в то время как ленивый квантор *? гарантирует, что вы не пройти мимо конца строки в кавычках. Работает с .NET Framework RE классов

13

Как предусмотрено ePharaoh, ответ

/"([^"\\]*(\\.[^"\\]*)*)"/ 

Чтобы иметь выше, применяются к или одинарные кавычки или строк в двойных кавычках, используйте

/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/ 
0

Если это выполняется поиск с самого начала, может быть, это может работать?

\"((\\\")|[^\\])*\" 
0

Более обширная версия https://stackoverflow.com/a/10786066/1794894

/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/ 

Эта версия также содержит

  1. Минимальной длину котировки 50
  2. Extra типа котировок (открытый и закрыть )
0

бездельничал в regexpal и в конечном итоге с этим регулярным выражением: (Не спрашивайте меня, как это работает, я с трудом понимаю даже то я писал его лол)

"(([^"\\]?(\\\\)?)|(\\")+)+" 
7

Большинство решений, предлагаемых здесь, используют альтернативный повторение пути (т. е. (A | B) *.

Вы можете столкнуться с переполнением стека на больших входах, поскольку некоторый компилятор шаблонов реализует это с помощью рекурсии.

Java, например: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6337993

Что-то вроде этого: "(?:[^"\\]*(?:\\.)?)*", или один при условии, Ги Бедфорд позволит сократить количество шагов при разборе избежать большинства переполнения стека.

5
/"(?:[^"\\]++|\\.)*+"/ 

Взятые прямо из man perlre на системе Linux с Perl 5.22.0 установлен. В качестве оптимизации это регулярное выражение использует «posessive» форму как +, так и *, чтобы предотвратить обратное отслеживание, поскольку заранее известно, что строка без закрывающей цитаты не будет соответствовать ни в коем случае.

3

Этот продукт отлично работает на PCRE и не падает с помощью StackOverflow.

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

Объяснение:

  1. Каждая строка в кавычках начинается с Char: ";
  2. Может содержать любое количество символов: .*? {Lazy match}; завершение символом небезопасности [^\\];
  3. Оператор (2) является ленивым (!) Необязательным, потому что строка может быть пустой (""). Итак: (.*?[^\\])??
  4. И наконец, каждая строка с кавычками заканчивается символом Char ("), но ему может предшествовать четное число пар знаков выхода (\\\\)+; и это Greedy (!) необязательно: ((\\\\)+)?+ {Greedy matching}, строка bacause может быть пустой или без конечных пар!
1

здесь один, который работает с обоими «и", и вы легко можете добавить другие в начале.

("|')(?:\\\1|[^\1])*?\1

он использует обратной ссылки (\ 1) матч exactley, что в первой группе (» или ').

http://www.regular-expressions.info/backref.html

0

вариант, который не затрагивал перед:

  1. Reverse строку.
  2. Выполнение сопоставления на инвертированной строке.
  3. Переверните соответствующие строки.

У этого есть дополнительный бонус, позволяющий правильно сопоставлять скрытые открытые теги.

Допустим, у вас была следующая строка; String \"this "should" NOT match\" and "this \"should\" match" Здесь \"this "should" NOT match\" не следует сопоставлять и "should" должно быть. Кроме того, this \"should\" match должен быть сопоставлен и \"should\" не должен.

Первый пример.

// The input string. 
const myString = 'String \\"this "should" NOT match\\" and "this \\"should\\" match"'; 

// The RegExp. 
const regExp = new RegExp(
    // Match close 
    '([\'"])(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))' + 
    '((?:' + 
     // Match escaped close quote 
     '(?:\\1(?=(?:[\\\\]{2})*[\\\\](?![\\\\])))|' + 
     // Match everything thats not the close quote 
     '(?:(?!\\1).)' + 
    '){0,})' + 
    // Match open 
    '(\\1)(?!(?:[\\\\]{2})*[\\\\](?![\\\\]))', 
    'g' 
); 

// Reverse the matched strings. 
matches = myString 
    // Reverse the string. 
    .split('').reverse().join('') 
    // '"hctam "\dluohs"\ siht" dna "\hctam TON "dluohs" siht"\ gnirtS' 

    // Match the quoted 
    .match(regExp) 
    // ['"hctam "\dluohs"\ siht"', '"dluohs"'] 

    // Reverse the matches 
    .map(x => x.split('').reverse().join('')) 
    // ['"this \"should\" match"', '"should"'] 

    // Re order the matches 
    .reverse(); 
    // ['"should"', '"this \"should\" match"'] 

Хорошо, теперь, чтобы объяснить RegExp. Это регулярное выражение может быть легко разбито на три части. Как следует:

# Part 1 
(['"])   # Match a closing quotation mark " or ' 
(?!   # As long as it's not followed by 
    (?:[\\]{2})* # A pair of escape characters 
    [\\]   # and a single escape 
    (?![\\])  # As long as that's not followed by an escape 
) 
# Part 2 
((?:   # Match inside the quotes 
(?:   # Match option 1: 
    \1   # Match the closing quote 
    (?=   # As long as it's followed by 
    (?:\\\\)* # A pair of escape characters 
    \\  # 
    (?![\\]) # As long as that's not followed by an escape 
)   # and a single escape 
)|   # OR 
(?:   # Match option 2: 
    (?!\1).  # Any character that isn't the closing quote 
) 
)*)   # Match the group 0 or more times 
# Part 3 
(\1)   # Match an open quotation mark that is the same as the closing one 
(?!   # As long as it's not followed by 
    (?:[\\]{2})* # A pair of escape characters 
    [\\]   # and a single escape 
    (?![\\])  # As long as that's not followed by an escape 
) 

Это, вероятно, намного яснее в виде изображения: генерируется с использованием Jex's Regulex

Image on github (JavaScript Regular Expression Visualizer.) К сожалению, у меня нет достаточно высокой репутации, чтобы включить изображения, таким образом, это просто ссылка на данный момент.

Вот это суть примера функции, используя эту концепцию, это немного более продвинутый: https://gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js

Смежные вопросы