2012-03-13 13 views
5

से टिप्पणियों को हटाने के लिए नियमित अभिव्यक्ति मैं SQL कथन से टिप्पणियों को हटाने के लिए नियमित अभिव्यक्ति के साथ आने का प्रयास कर रहा हूं।SQL कथन

इस regex लगभग काम करता है:

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

Excepth है कि पिछले भाग का क्या करता है नहीं "-" टिप्पणी बहुत अच्छी तरह से। समस्या एसक्यूएल तारों को संभालने में है, जो '' के साथ सीमित है।

उदाहरण के लिए, अगर मैं

SELECT ' -- Hello -- ' FROM DUAL 

है यह मेल नहीं करना चाहिए, लेकिन यह मिलान है।

यह एएसपी/वीबीस्क्रिप्ट में है।

मैंने दाएं से बाएं मिलान करने के बारे में सोचा है, लेकिन मुझे नहीं लगता कि वीबीस्क्रिप्ट का रेगेक्स इंजन इसका समर्थन करता है। नकारात्मक दिखने के साथ झुकाव की कोशिश की लेकिन परिणाम अच्छे नहीं थे।

उत्तर

1

जैसा कि आपने कहा था कि आपका बाकी रेगेक्स ठीक है, मैंने अंतिम भाग पर ध्यान केंद्रित किया। तुम सब करने की ज़रूरत है सत्यापित करें कि -- शुरुआत में है और उसके बाद सुनिश्चित करें कि यह सभी डैश को हटा देखते हैं यदि एक से अधिक 2. अंत regex नीचे

(^[--]+) 
ऊपर

है सिर्फ अगर आप निकालना चाहते हैं है टिप्पणी डैश और पूरी लाइन नहीं। आप

(^--.*) 
+0

हाय जस्टिन है ... मदद के लिए धन्यवाद। अभी भी इनलाइन टिप्पणियों के साथ समस्या बनी हुई है जो शुरुआत में शुरू नहीं होती हैं। पसंद की तरह '- हैलो -' डुएल से - टिप्पणी जिसे हटाया जाना चाहिए –

+0

कोई समस्या नहीं है, और ओवरफ़्लो ढेर में आपका स्वागत है। कृपया याद रखें कि यहां प्रशंसा दिखाने का तरीका अपवॉट और स्वीकृत उत्तरों (उत्तर के बगल में स्थित चेकमार्क) के माध्यम से है। अधिक जानकारी [एफएक्यू] में मिल सकती है, विशेष रूप से [एफएक्यू # HowToAsk] –

4

PHP में यदि आप पंक्ति के अंत तक यह बाद सब कुछ करना चाहते हैं तो नीचे दिए गए चला सकते हैं, भी, मैं टिप्पणी हटाएं एसक्यूएल के लिए इस कोड का उपयोग कर रहा:

$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

कैसे पूछें यह तारकीय है लेकिन मुझे अंत में ट्रिमिंग पसंद नहीं आया, क्योंकि यह उन नईलाइनों को हटा सकता है जो वास्तव में वांछनीय/आवश्यक हो सकते हैं (जैसा कि जब कोड के बाद एक इनलाइन टिप्पणी से पहले कोई स्थान नहीं होता है ... लोग ऐसा करते हैं: |)। उद्धरण सूची में बैकटिक्स भी जोड़ा गया। तो मैं इसका उपयोग कर रहा हूं: $ sqlComments = '@ (([\' "'])। *? [^ \\\] \ 2) | ((?: \ # | -)। *? $ |/\ * (?: [^/*] |/(?! \ *) | \ * (?! /) | (? आर)) * \ * \ /) + @ एमएस '; – dkloke

+0

यह regexp segfaults (php 5.6) या शुरुआत में लंबी टिप्पणियों वाले प्रश्नों पर NULL (php 7+) देता है, उदाहरण के लिए ' /* 8kb डमी टेक्स्ट */ चुनें 1; ' –

+0

मैं इस regexp के माध्यम से लगभग 120k प्रश्नों को चलाता हूं और एक क्वेरी के बीच में टिप्पणियों का पता लगाने में इसमें कुछ प्रमुख त्रुटियां हैं। "-" (डबल डैश स्ट्रिंग) युक्त ठीक से encapsulated तारों को हटा दिया जाता है। –

1

इस कोड काम करता है मेरे लिए:

function strip_sqlcomment ($string = '') { 
    $RXSQLComments = '@(--[^\r\n]*)|(\#[^\r\n]*)|(/\*[\w\W]*?(?=\*/)\*/)@ms'; 
    return (($string == '') ? '' : preg_replace($RXSQLComments, '', $string)); 
} 
एक छोटे से regex के साथ

यह किसी भी भाषा

0

मूल में टिप्पणी पट्टी करने के लिए इस्तेमाल किया जा सकता है tweak ly, मैंने @Adrien Gibrat के समाधान का उपयोग किया। हालांकि, मैं ऐसी परिस्थिति में आया जहां यह उद्धृत तारों को पार्स नहीं कर रहा था, ठीक है, अगर मेरे पास पिछले कुछ के साथ कुछ भी था। मैंने इसे लिखना समाप्त कर दिया, इसके बजाय:

'[^']*(?!\\)'(*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) 

कृपया ध्यान दें कि पीसीआरई उपलब्ध होने पर इसका उपयोग किया जाना चाहिए। तो, मेरे मामले में, मैं अपनी PHP लाइब्रेरी में इसकी विविधता का उपयोग कर रहा हूं।

Example

+1

यह मीठा है! मैंने regexp को अद्यतन किया है, इसलिए यह न केवल एकल उद्धरणों में, बल्कि डबल कोट्स और बैकटीक्स में टिप्पणियों को अनदेखा करता है - https://regex101.com/r/GXb0a5/2 –

0

कृपया मेरा उत्तर here देखते हैं। यह लाइन टिप्पणियों और ब्लॉक टिप्पणियों, यहां तक ​​कि नेस्टेड ब्लॉक टिप्पणियों दोनों के लिए काम करता है। मुझे लगता है कि आपको संतुलन समूहों के साथ रेगेक्स का उपयोग करने की आवश्यकता है, जो AFAIK VBScript में उपलब्ध नहीं है।

-1

सभी PHP लोगों के लिए: कृपया इस लाइब्रेरी का उपयोग करें - https://github.com/jdorn/sql-formatter। मैं अब कुछ वर्षों से एसक्यूएल से टिप्पणियों को अलग करने के साथ काम कर रहा हूं और एकमात्र वैध समाधान टोकननाइज़र/राज्य मशीन होगा, जिसे मैंने लिखने के लिए आलसी विरोध किया था।कुछ दिन पहले मैंने इस lib को पाया और इसके माध्यम से 120k प्रश्नों को चलाया और केवल एक बग (https://github.com/jdorn/sql-formatter/issues/93) पाया, जो हमारे फोर्क https://github.com/keboola/sql-formatter में तुरंत तय किया गया है।

उपयोग सरल

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

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

@ बामिट्यूगेन धन्यवाद, उत्तर को ठीक किया गया। –

संबंधित मुद्दे