2012-03-13 13 views
5

Bir SQL deyiminden yorumları kaldırmak için normal bir ifade ile gelmeye çalışıyorum.SQL deyiminden yorumları kaldırmak için düzenli ifade

Bu regex neredeyse çalışır:

(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|'(?:[^']|'')*'|(--.*) 

Excepth son bölüm idare etmediğini "-" yorumlar çok iyi. Sorun, '' ile sınırlandırılmış SQL dizelerini işlemektir.

i

SELECT ' -- Hello -- ' FROM DUAL 

var Örneğin, eğer aynı değil, ama o eşleşen ediyor.

Bu ASP/VBscript dosyasındadır.

Sağdan sola eşleşmeyi düşündüm ancak VBScript'in normal ifade motorunun bunu desteklediğini sanmıyorum. Ayrıca olumsuz bakışla uğraşmaya çalıştı ama sonuçlar iyi değildi.

cevap

1

İlacınızın geri kalanının iyi olduğunu söylediğin gibi, son bölüme odaklandım. Yapmanız gereken tek şey kaldırmak istediğiniz sadece eğer daha fazla 2. uç regex yukarıda

(^[--]+) 

altındaysa varsa o tüm çizgi kaldırır emin olun, sonra -- başında olduğundan ve bir Yorum çizgileri ve tüm çizgi değil. Eğer hattın sonuna ondan sonra her şeyi istiyorsun durumunda da, aşağıda PHP

(^--.*) 
+0

Merhaba Justin basittir. Başlangıçta başlamayan satır içi yorumlarla ilgili sorun hala devam ediyor. SELECT 'gibi - Merhaba -' DAN DAN - yorum kaldırılması gereken –

+0

Sorun yok ve taşma yığınına hoş geldiniz. Burada takdir gösterme şeklinin, upvotes ve kabul edilen cevaplardan (cevabın yanındaki onay işareti) olduğunu lütfen unutmayın. [FAQ] 'da daha fazla bilgi bulunabilir, özellikle de [FAQ # HowToAsk] Nasıl Yapılır –

4

çalıştırabilir, ben yorumsuz SQL için bu kodu kullanıyorum:

$sqlComments = '@(([\'"]).*?[^\\\]\2)|((?:\#|--).*?$|/\*(?:[^/*]|/(?!\*)|\*(?!/)|(?R))*\*\/)\s*|(?<=;)\[email protected]'; 
/* Commented version 
$sqlComments = '@ 
    (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions 
    |(     # $3 : Match comments 
     (?:\#|--).*?$ # - Single line comments 
     |    # - Multi line (nested) comments 
     /\*    # . comment open marker 
      (?: [^/*] # . non comment-marker characters 
       |/(?!\*) # . ! not a comment open 
       |\*(?!/) # . ! not a comment close 
       |(?R) # . recursive case 
      )*   # . repeat eventually 
     \*\/    # . comment close marker 
    )\s*     # Trim after comments 
    |(?<=;)\s+   # Trim after semi-colon 
    @msx'; 
*/ 
$uncommentedSQL = trim(preg_replace($sqlComments, '$1', $sql)); 
preg_match_all($sqlComments, $sql, $comments); 
$extractedComments = array_filter($comments[ 3 ]); 
var_dump($uncommentedSQL, $extractedComments); 
+0

Bu bir yıldızdır ancak sonundaki kırpmayı beğenmedim, çünkü aslında istenen/gerekli olabilecek yeni satırları kaldırabilir koddan sonra satır içi bir açıklama yapılmadığında, insanlar bunu yapar: |). Ayrıca teklif listesine backticks eklendi. Yani kullanıyorum: $ sqlComments = '@ (([\' "']). *? [^ \\\] \ 2) | ((?: \ # | -). *? $ |/\ * (?: [^/*] |/(?! \ *) | \ * (?! /) | (? R)) * \ * \ /) + @ ms '; – dkloke

+0

Bu regexp segfaults (php 5.6) ya da döner NULL örn ' /* burada koymak/ 1 SEÇ * kukla metin 8KB başında uzun yorumlarla sorgularında (php 7+); bu regexp aracılığıyla etrafında 120k sorguları koştu ' –

+0

ve Bir sorgunun ortasındaki yorumları tespit etmede bazı önemli kusurları vardır: "-" (çift çizgi dizgisi) içeren düzgün şekilde kapsüllenmiş dizgiler kaldırılır. –

1

Bu kod işleri Benim için: küçük bir regex ile

function strip_sqlcomment ($string = '') { 
    $RXSQLComments = '@(--[^\r\n]*)|(\#[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)@ms'; 
    return (($string == '') ? '' : preg_replace($RXSQLComments, '', $string)); 
} 

herhangi bir dilde

0

Orjinal açıklamalarda şerit kullanılabilir çimdik ly, @Adrien Gibrat'ın çözümünü kullandım. Ancak, içinde bir '-' ile bir şey varsa, alıntı dizeleri ayrıştırmadığı bir duruma rastladım. Bunun yerine, bu yazma sona erdi: PCRE kullanılabilir olduğunda

'[^']*(?!\\)'(*SKIP)(*F)  # Make sure we're not matching inside of quotes 
|(?m-s:\s*(?:\-{2}|\#)[^\n]*$) # Single line comment 
|(?: 
    \/\*.*?\*\/     # Multi-line comment 
    (?(?=(?m-s:\h+$))   # Get trailing whitespace if any exists and only if it's the rest of the line 
    \h+ 
) 
) 

# Modifiers used: 'xs' ('g' can be used as well, but is enabled by default in PHP) 

bu kullanılması gerektiğini lütfen unutmayın. Yani, benim durumumda, PHP kütüphanemde bunun bir varyasyonunu kullanıyorum.

Example

+1

Bu tatlı! Regexp'i güncelledim, böylece sadece tek tırnakta değil, çift tırnak ve backticklerde de yorumları görmezden geliyor - https://regex101.com/r/GXb0a5/2 –

0

cevabım here bakınız. satır yorumları için ve blok yorumları için geçerlidir, hatta iç içe geçmiş blok yorumlar. Sanırım VHDScript'te AFAIK bulunmayan dengeleme grupları ile regex kullanmanız gerekir.

-1

Tüm PHP üyeleri için: Lütfen bu kütüphaneyi kullanın - https://github.com/jdorn/sql-formatter. Şimdi birkaç yıldan beri SQL'den yorumlar aldırmakla uğraşıyordum ve tek geçerli çözüm yazı yazmaya karşı koyduğum bir tokenizer/state makinesi olurdu.Birkaç gün önce bu kütüphaneyi buldum ve 120k sorgularını araştırdım ve https://github.com/keboola/sql-formatter numaralı çatalımızda hemen düzeltilen tek bir hata (https://github.com/jdorn/sql-formatter/issues/93) bulundu.

kullanım ... yardım için teşekkürler

$query <<<EOF 
/* 
    my comments 
*/ 
SELECT 1; 
EOF; 

$bareQuery = \SqlFormatter::removeComments($query); 
// prints "SELECT 1;" 
print $bareQuery; 
+0

@BaummitAugen Teşekkürler, cevabı düzelttim. –