" It's big \"problem "
Normal ifade kullanarak alt dizeyi nasıl elde ederim ?
s = ' function(){ return " It\'s big \"problem "; }';
" It's big \"problem "
Normal ifade kullanarak alt dizeyi nasıl elde ederim ?
s = ' function(){ return " It\'s big \"problem "; }';
Yanıtlar:
/"(?:[^"\\]|\\.)*"/
The Regex Coach ve PCRE Workbench'te çalışır.
JavaScript'te test örneği:
var s = ' function(){ return " Is big \\"problem\\", \\no? "; }';
var m = s.match(/"(?:[^"\\]|\\.)*"/);
if (m != null)
alert(m);
(?:...)
pasif veya yakalamayan bir gruptur. Daha sonra geri referans alınamayacağı anlamına gelir.
/(["'])(?:[^\1\\]|\\.)*?\1/
var s = ' my \\"new\\" string and \"this should be matched\"';
, bu yaklaşım beklenmedik sonuçlara yol açacaktır.
Bu, birçok linux dağıtımında bulunan nanorc.sample'den geliyor. C tarzı dizelerin sözdizimi vurgulaması için kullanılır
\"(\\.|[^\"])*\"
var s = ' my \\"new\\" string and \"this should be matched\"';
, bu yaklaşım beklenmedik sonuçlara yol açacaktır.
" \"(\\\\.|[^\\\"])*\" "
EPharaoh tarafından sağlandığı gibi, cevap
/"([^"\\]*(\\.[^"\\]*)*)"/
Yukarıdakilerin tek tırnaklı veya çift tırnaklı dizelere uygulanmasını sağlamak için kullanın
/"([^"\\]*(\\.[^"\\]*)*)"|\'([^\'\\]*(\\.[^\'\\]*)*)\'/
Burada sağlanan çözümlerin çoğu alternatif tekrar yollarını kullanır, yani (A | B) *.
Bazı desen derleyicileri bunu özyineleme kullanarak gerçekleştirdiğinden, büyük girdilerde yığın taşmalarıyla karşılaşabilirsiniz.
Örneğin Java: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6337993
Bunun gibi bir şey:
"(?:[^"\\]*(?:\\.)?)*"
veya Guy Bedford tarafından sağlanan, yığın taşmalarının çoğunu önleyerek ayrıştırma adımlarının miktarını azaltacaktır.
/"(?:[^"\\]++|\\.)*+"/
man perlre
Perl 5.22.0 kurulu bir Linux sisteminden doğrudan alınmıştır . Bir optimizasyon olarak, bu normal ifade, her ikisinin de 'pozitif' biçimini kullanır +
ve *
geriye doğru izlemeyi önlemek için önceden bilinir, çünkü kapanış tırnağı olmayan bir dizenin hiçbir durumda eşleşmeyeceği önceden bilinmektedir.
/(["\']).*?(?<!\\)(\\\\)*\1/is
alıntılanmış herhangi bir dizeyle çalışmalıdır
Bu, PCRE'de mükemmel çalışır ve StackOverflow'a düşmez.
"(.*?[^\\])??((\\\\)+)?+"
Açıklama:
"
:;.*?
{Geç eşleşme}; kaçış olmayan karakterle biten [^\\]
;(.*?[^\\])??
"
) ile biter , ancak önünde çift sayıda kaçış işareti çifti bulunabilir (\\\\)+
; ve Açgözlü (!) isteğe bağlıdır: ((\\\\)+)?+
{Açgözlü eşleştirme}, temelde dizge boş olabilir veya çift bitmeyen olabilir!"(.*?[^\\])?(\\\\)*"
burada hem "hem de" ile çalışan bir tane var ve başlangıçta başkalarını kolayca ekleyebilirsiniz.
( "| ') (?: \\\ 1 | [^ \ 1])? * \ 1
geri referans (\ 1), birinci grupta ("veya ') olanla tam olarak eşleşir.
[^\1]
bunun yerine geçmelidir .
çünkü geriye dönük referans diye bir şey yoktur ve hiçbir şekilde önemi yoktur. ilk koşul, kötü bir şey olmadan önce daima eşleşecektir.
[^\1]
ile .
etkili bir şekilde bu regex değiştirecek ("|').*?\1
ve o zaman eşleşir "foo\"
içinde "foo \" bar"
. Bununla birlikte, [^\1]
gerçekten işe başlamak zor. @ Mathiashansen - Kullanışsız ve pahalı olanlarda daha iyi durumdasınız(?!\1).
(bu nedenle, bir miktar verimlilik temizliği ile tüm normal ifadeler olabilir (["'])(?:\\.|(?!\1).)*+\1
. +
Motorunuz desteklemiyorsa isteğe bağlıdır.
Daha önce değinilmeyen bir seçenek:
Bu, kaçan açık etiketleri doğru şekilde eşleştirebilme avantajına sahiptir.
Aşağıdaki dizeye sahip olduğunuzu varsayalım; String \"this "should" NOT match\" and "this \"should\" match"
Burada \"this "should" NOT match\"
eşleştirilmemeli ve "should"
olmalıdır. Bunun üzerine this \"should\" match
uyumlu ve gerektiği \"should\"
olmamalı.
Önce bir örnek.
// 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"']
Tamam, şimdi RegExp'i açıklayalım. Bu regexp kolayca üç parçaya bölünebilir. Aşağıdaki gibi:
# 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
)
Bu muhtemelen resim biçiminde çok daha nettir: Jex'in Regulex'i kullanılarak oluşturulmuştur
Github üzerindeki resim (JavaScript Normal İfade Görselleştirici.) Üzgünüm, resimleri eklemek için yeterince yüksek itibarım yok, bu yüzden şimdilik sadece bir bağlantı.
İşte biraz daha gelişmiş olan bu kavramı kullanan örnek bir fonksiyonun özü: https://gist.github.com/scagood/bd99371c072d49a4fee29d193252f5fc#file-matchquotes-js
Normal ifadelerin string-y olan her şey için sihirli ifadeler olmadığını hatırlamak gerekir. Bazı şeyler bir imleç ve doğrusal, manuel arama ile yapmak daha kolaydır. Bir CFL bu işi oldukça önemsiz bir şekilde yapar, ancak çok fazla CFL uygulaması yoktur (afaik).
Https://stackoverflow.com/a/10786066/1794894'ün daha kapsamlı bir sürümü
/"([^"\\]{50,}(\\.[^"\\]*)*)"|\'[^\'\\]{50,}(\\.[^\'\\]*)*\'|“[^”\\]{50,}(\\.[^“\\]*)*”/
Bu sürüm ayrıca şunları içerir:
“
ve kapalı ”
)Etrafında haberci regexpal ve bu regex ile sona erdi: (nasıl çalıştığını Do yazdım bile tho zar zor lol anlamak bana sormayın)
"(([^"\\]?(\\\\)?)|(\\")+)+"
Baştan aranırsa belki bu işe yarayabilir?
\"((\\\")|[^\\])*\"
Bazı dosyaların ayrıştırılmasına engel olabilecek alıntılanmış dizeleri kaldırmaya çalışırken benzer bir sorunla karşılaştım.
Bulabileceğiniz tüm kıvrımlı normal ifadeleri yenen iki adımlı bir çözüm buldum:
line = line.replace("\\\"","\'"); // Replace escaped quotes with something easier to handle
line = line.replaceAll("\"([^\"]*)\"","\"x\""); // Simple is beautiful
Okuması daha kolay ve muhtemelen daha verimli.
IDE'niz IntelliJ Idea ise, tüm bu baş ağrılarını unutabilir ve normal ifadenizi bir String değişkeninde saklayabilirsiniz ve çift tırnak içine kopyalayıp yapıştırdığınızda otomatik olarak normal ifadeyi kabul edilebilir bir biçime dönüşür.
Java'da örnek:
String s = "\"en_usa\":[^\\,\\}]+";
artık bu değişkeni regexp'inizde veya herhangi bir yerde kullanabilirsiniz.