2009-11-01 16 views
14

में टिप्पणियां ढूंढने के लिए इस समय जावा के साथ मजेदारजावा - नियमित रूप से अभिव्यक्ति कोड

// some comment 
class Main { 
    /* blah */ 
    // /* foo 
    foo(); 
    // foo */ 
    foo2(); 
    /* // foo2 */ 
} 

उस में सभी टिप्पणियों पाता है और उन्हें निकालता है: मैं एक प्रोग्राम है जो मानक इनपुट से एक कोड पढ़ता है (लाइन द्वारा लाइन, उदाहरण के लिए) लिखने के लिए, की तरह चाहते हैं।

System.out.print("We can use /* comments */ inside a string of course, but it shouldn't start a comment"); 

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

private static String ParseCode(String pCode) 
{ 
    String MyCommentsRegex = "(?://.*)|(/\\*(?:.|[\\n\\r])*?\\*/)"; 
    return pCode.replaceAll(MyCommentsRegex, " "); 
} 

लेकिन यह सभी मामलों के लिए काम करने के लिए नहीं लगता है, विचार regex से अलग? अग्रिम धन्यवाद।

+0

मुझे लगता है कि आपका सटीक उदाहरण खराब है: स्ट्रिंग के अंदर की करीबी टिप्पणी टिप्पणी बंद कर देगी। हालांकि, एक स्ट्रिंग के अंदर एक खुली टिप्पणी जो किसी टिप्पणी में नहीं है, वह एक प्रारंभ नहीं होगी। – Grandpa

+0

हाँ, मेरा बुरा। मैं यहाँ कुछ मुश्किल देने की कोशिश कर रहा था और खुद को धोखा दे रहा था। – brovar

+0

यदि आप इसे करने के बाद इसे समेकित कर सकते हैं और जवाब में डाल सकते हैं तो मैं सराहना करता हूं। मैं भी इसी तरह के समाधान की तलाश कर रहा हूं – Ravisha

उत्तर

0

एक और विकल्प कुछ पुस्तकालयों का उपयोग एएसटी पार्सिंग का समर्थन करना है, उदाहरण के लिए org.eclipse.jdt.core में सभी एपीआई हैं जिन्हें आपको और अधिक करने की आवश्यकता है। लेकिन तब है कि सिर्फ एक विकल्प :)

+0

इसे यहां उपयोग करने की अनुमति नहीं है - यह एक शर्त है जब नियमों में से एक केवल मूल पैकेज का उपयोग कर रहा है;) लेकिन फिर भी धन्यवाद, मुझे लेना होगा इसे देखो – brovar

3

पिछले उदाहरण कोई समस्या नहीं मुझे लगता है कि है:

/* we comment out some code 
System.out.print("We can use */ inside a string of course"); 
we end the comment */ 

... क्योंकि टिप्पणी वास्तव में "We can use */ साथ समाप्त होता है। यह कोड संकलित नहीं करता है।

int/*comment*/foo=3; 

आपका पैटर्न में इस बदलना होगा:

intfoo=3; 

... अमान्य कोड क्या है

लेकिन मैं एक और समस्या पैदा करने वाले मामला है। "" के बजाय " " के साथ अपनी टिप्पणियों को बेहतर ढंग से बदलें।

+0

बस उसे भी देखा, धन्यवाद। – brovar

3

मुझे लगता है कि नियमित अभिव्यक्तियों का उपयोग करके 100% सही समाधान या तो अमानवीय या असंभव है (खाते में भाग लेना आदि)।

मेरा मानना ​​है कि सबसे अच्छा विकल्प एएनटीएलआर का उपयोग करेगा- मेरा मानना ​​है कि वे जावा व्याकरण भी प्रदान कर सकते हैं जिसका आप उपयोग कर सकते हैं।

+0

मैं एक कोड पार्सर/अनुवादक या कुछ भी समान नहीं बना रहा हूं, बस एक सरल प्रोग्राम बनाने की कोशिश कर रहा हूं जो ऊपर वर्णित कार्य करेगा;) – brovar

+0

@brovar - वह कह रहा है कि आप इसे बिना किसी पार्सर के कर सकते हैं। –

23

आप पहले से ही इसे छोड़ चुके हैं लेकिन मैं समस्या से चिंतित था।

मेरा मानना ​​है कि यह एक आंशिक समाधान है ...

मूल निवासी regex:

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

जावा में:

String clean = original.replaceAll("//.*|(\"(?:\\\\[^\"]|\\\\\"|.)*?\")|(?s)/\\*.*?\\*/", "$1 "); 

यह ठीक से तार में एम्बेडेड टिप्पणी को संभालने के लिए प्रकट होता है और साथ ही तारों के अंदर उद्धरण से ठीक से बच निकला। मैंने जांच करने के लिए कुछ चीजें फेंक दी लेकिन पूरी तरह से नहीं।

एक समझौता है कि कोड में सभी ब्लॉक उनके बाद अंतरिक्ष के साथ समाप्त हो जाएंगे। इस सरल को हल करना और समस्या को हल करना बहुत मुश्किल होगा:

int/* some comment */foo = 5; 

एक साधारण Matcher।ढूंढें/संलग्न करें रिप्लेसमेंट लूप सशर्त रूप से किसी स्थान के साथ प्रतिस्थापित करने से पहले समूह (1) की जांच कर सकता है और केवल कोड की एक मुट्ठी भर होगी। शायद एक पूर्ण अप पार्सर से अभी भी आसान है। (यदि कोई दिलचस्पी लेता है तो मैं मैचर लूप भी जोड़ सकता हूं।)

+0

नोट: "आंशिक समाधान" से मेरा मतलब है कि मैं अभी तक एक मामले के साथ नहीं आया है, जहां यह विफल रहता है और इसका उपयोग एक प्रतिस्थापन में सख्ती से कर रहा है() "उद्धृत" स्ट्रिंग के बाद एक अतिरिक्त स्थान जोड़ देगा। – PSpeed

+0

हाय, आपके उत्तर के लिए धन्यवाद, मैंने अभी इसे पाया है। मैंने पहले से ही समस्या को हल कर लिया है, लेकिन जब मैं घर जाता हूं, तो मैं इसे आजमाने की कोशिश करता हूं, क्योंकि यह काफी दिलचस्प लगता है। – brovar

+0

क्षमा करें, लेकिन यह regex '\t आप पहले से ही इस पर छोड़ दिया हो सकता है लेकिन मैं समस्या से चिंतित था। मेरा मानना ​​है कि यह एक आंशिक समाधान है ... मूल निवासी regex: //.*|("(?:\\[^"]|\\"|.)*?")|(?s) /\*.*?\*/ 'मिलान स्ट्रिंग str =' "एक ज़िप फ़ंक्शन को कॉल करना" '; –

3

मैं इस समाधान के साथ समाप्त हुआ।

public class CommentsFun { 
    static List<Match> commentMatches = new ArrayList<Match>(); 

    public static void main(String[] args) { 
     Pattern commentsPattern = Pattern.compile("(//.*?$)|(/\\*.*?\\*/)", Pattern.MULTILINE | Pattern.DOTALL); 
     Pattern stringsPattern = Pattern.compile("(\".*?(?<!\\\\)\")"); 

     String text = getTextFromFile("src/my/test/CommentsFun.java"); 

     Matcher commentsMatcher = commentsPattern.matcher(text); 
     while (commentsMatcher.find()) { 
      Match match = new Match(); 
      match.start = commentsMatcher.start(); 
      match.text = commentsMatcher.group(); 
      commentMatches.add(match); 
     } 

     List<Match> commentsToRemove = new ArrayList<Match>(); 

     Matcher stringsMatcher = stringsPattern.matcher(text); 
     while (stringsMatcher.find()) { 
      for (Match comment : commentMatches) { 
       if (comment.start > stringsMatcher.start() && comment.start < stringsMatcher.end()) 
        commentsToRemove.add(comment); 
      } 
     } 
     for (Match comment : commentsToRemove) 
      commentMatches.remove(comment); 

     for (Match comment : commentMatches) 
      text = text.replace(comment.text, " "); 

     System.out.println(text); 
    } 

    //Single-line 

    // "String? Nope" 

    /* 
    * "This is not String either" 
    */ 

    //Complex */ 
    ///*More complex*/ 

    /*Single line, but */ 

    String moreFun = " /* comment? doubt that */"; 

    String evenMoreFun = " // comment? doubt that "; 

    static class Match { 
     int start; 
     String text; 
    } 
} 
+0

वाह !! बहुत बढ़िया!! – Sangeeta

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