это фрагмент, который я использую, он удаляет все вещи между APA и BEPA (через несколько строк, включая удаление APA, BEPA) во всех файлах ниже текущего каталога, исключает каталог .svn
find . \! -path '*.svn*' -type f -exec sed -i -n '1h;1!H;${;g;s/APA[ \t\r\n]*BEPA//g;p}' {} \;
/"(?:[^"\\]++|\\.)*+"/
Взято прямо из man perlre
в системе Linux с установленным Perl 5.22.0. В качестве оптимизации это регулярное выражение использует «posessive» форму как +
, так и *
для предотвращения обратного отслеживания, поскольку заранее известно, что строка без закрывающей цитаты не будет соответствовать ни в коем случае.
Более обширная версия https://stackoverflow.com/a/10786066/1794894
/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/
Эта версия также содержит
“
и закрыть ”
) Если поиск выполняется с самого начала, возможно, это может работать?
\"((\\\")|[^\\])*\"
Как указано в ePharaoh, ответ:
/"([^"\\]*(\\.[^"\\]*)*)"/
Чтобы применить вышеприведенные к одиночным или двойным кавычками строки, используйте
/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
Нужно помнить, что регулярные выражения не являются серебряной пулей для всех строк-y. Некоторые вещи проще сделать с помощью курсора и линейного, ручного поиска. CFL будет делать трюк довольно тривиально, но не так много реализаций CFL (afaik).
Большинство предлагаемых решений используют альтернативные пути повторения, т. е. (A | B) *.
Вы можете столкнуться с переполнением стека на больших входах, поскольку какой-то компилятор шаблонов реализует это с помощью рекурсии.
Java, например: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6337993
Что-то вроде этого: "(?:[^"\\]*(?:\\.)?)*"
или один предоставленный Гаем Бедфордом, уменьшит количество шагов синтаксического анализа, избегая большинства переполнений стека.
здесь работает тот, который работает с «и», и вы легко добавляете других в начале.
("|')(?:\\\1|[^\1])*?\1
он использует обратную ссылку (\ 1), чтобы точно совместить то, что находится в первой группе (" или ').
[^\1]
следует заменить на .
, потому что нет такой вещи, как анти-обратная ссылка, и это не имеет никакого значения. первое условие всегда будет соответствовать, прежде чем произойдет что-либо плохое.
– Seph Reed
2 November 2017 в 07:15
Пробел в regexpal и закончил с этим регулярным выражением: (Не спрашивайте меня, как это работает, я едва понимаю даже то, что я написал его lol)
"(([^"\\]?(\\\\)?)|(\\")+)+"
/"(?:[^"\\]|\\.)*"/
Работает в Regex Coach и PCRE Workbench.
Пример теста в JavaScript:
var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);
(?:...)
- пассивная или не захватывающая группа. Это означает, что он не может быть обратный позже.
– magras
2 October 2014 в 17:27
/(["'])(?:[^\1\\]|\\.)*?\1/
– leo
3 May 2015 в 02:47
Опция, которая ранее не была затронута:
У этого есть дополнительный бонус, позволяющий правильно сопоставлять экранированные открытые теги.
Допустим, у вас была следующая строка; 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
"(?:\\"|.)*?"
Чередование \"
и .
проходит через экранированные кавычки, в то время как ленивый квантификатор *?
гарантирует, что вы не проходите мимо конца строки с кавычками. Работает с классами .NET Framework RE
/(["\']).*?(?<!\\)(\\\\)*\1/is
должен работать с любой цитируемой строкой
var s = ' my \\"new\\" string and \"this should be matched\"';
этот подход приведет к неожиданным результатам.
– Wiktor Stribiżew
25 July 2016 в 12:38
Это работает отлично на PCRE и не падает с помощью StackOverflow.
"(.*?[^\\])??((\\\\)+)?+"
Объяснение:
"
; .*?
{Lazy match}; завершение символом non escape [^\\]
; (.*?[^\\])??
"
), но ему может предшествовать четное число пар escape-пар (\\\\)+
; и это Greedy (!) необязательно: ((\\\\)+)?+
{Greedy matching}, строка bacause может быть пустой или без конечных пар! "(.*?[^\\])?(\\\\)*"
– Casimir et Hippolyte
17 March 2018 в 22:59
Я столкнулся с аналогичной проблемой, пытающейся удалить строки с кавычками, которые могут помешать анализу некоторых файлов.
Я закончил с двухступенчатым решением, которое превосходит любое запутанное регулярное выражение, которое вы можете найти: / g1]
line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful
Легче читать и, вероятно, более эффективно.