Regex: обнаружение совпадающих котировок [дубликат]

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

Итак, если вы используете Angular, React или любые другие фреймворки, которые делают два способа связывания данных, эта проблема просто исправлена ​​для вас, поэтому простым языком ваш результат undefined на первом этапе, поэтому вы получили result = undefined до получения данных, а затем, как только вы получите результат , он будет обновляться и присваиваться новому значению, которое отвечает на ваш вызов Ajax ...

Но как вы можете сделать это в чистом javascript или jQuery, например, как вы задали этот вопрос?

Вы можете использовать обратный вызов, обещание и недавно наблюдаемое, чтобы обрабатывать его для вас, например, в обещаниях мы имеем некоторые функции, такие как success () или then (), которые будут выполняться, когда ваши данные будут готовы для вас, с функцией обратного вызова или подписки на наблюдаемые.

Например, в вашем случае, в котором вы используете jQuery, вы можете сделать что-то вроде этого:

$(document).ready(function(){
    function foo() {
        $.ajax({url: "api/data", success: function(data){
            fooDone(data); //after we have data, we pass it to fooDone
        }});
    };

    function fooDone(data) {
        console.log(data); //fooDone has the data and console.log it
    };

    foo(); //call happens here
});

Для получения дополнительной информации n изучение обещаний и наблюдаемых, которые являются новыми способами для создания асинхронных материалов.

88
задан David 30 January 2015 в 17:22
поделиться

14 ответов

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

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

5
ответ дан ack 25 August 2018 в 20:25
поделиться

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

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

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

  1. Минимальная длина цитаты 50
  2. Экстра-тип кавычек (открыть и закрыть )
0
ответ дан Community 25 August 2018 в 20:25
поделиться

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

\"((\\\")|[^\\])*\"
0
ответ дан cxw 25 August 2018 в 20:25
поделиться

Как указано в ePharaoh, ответ:

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

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

/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
13
ответ дан Guy Bedford 25 August 2018 в 20:25
поделиться

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

0
ответ дан Henrik Paul 25 August 2018 в 20:25
поделиться

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

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

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

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

8
ответ дан Marc-André Poulin 25 August 2018 в 20:25
поделиться

здесь работает тот, который работает с «и», и вы легко добавляете других в начале.

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

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

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

1
ответ дан mathias hansen 25 August 2018 в 20:25
поделиться

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

"(([^"\\]?(\\\\)?)|(\\")+)+"
0
ответ дан Petter Thowsen 25 August 2018 в 20:25
поделиться
/"(?:[^"\\]|\\.)*"/

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

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

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

112
ответ дан Philip Kirkbride 25 August 2018 в 20:25
поделиться

Опция, которая ранее не была затронута:

  1. Отмените строку.
  2. Выполните сопоставление по инвертированной строке.

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

Допустим, у вас была следующая строка; 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

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

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

0
ответ дан scagood 25 August 2018 в 20:25
поделиться
"(?:\\"|.)*?"

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

8
ответ дан Tosh Afanasiev 25 August 2018 в 20:25
поделиться
/(["\']).*?(?<!\\)(\\\\)*\1/is

должен работать с любой цитируемой строкой

3
ответ дан user 25 August 2018 в 20:25
поделиться

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

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

Объяснение:

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

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

Я закончил с двухступенчатым решением, которое превосходит любое запутанное регулярное выражение, которое вы можете найти: / g1]

 line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
 line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful

Легче читать и, вероятно, более эффективно.

0
ответ дан マルちゃん だよ 25 August 2018 в 20:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: