2009-05-11 23 views
5

में एम्परसैंड से बचने के लिए मुझे एक स्ट्रिंग में सभी को प्रतिस्थापित करने की आवश्यकता है जो HTML इकाई का हिस्सा नहीं है। ताकि स्ट्रिंग "यह & entites > & <" वापस आ जाएगी "यह & entites > & <"रेगेक्स अनुकूलन - जावा

और मैं इस regex पैटर्न ले कर आए हैं: "& [एक-zA-Z0-9] {2 , 7}; "जो ठीक काम करता है। लेकिन मैं regex में बहुत कुशल नहीं हूं, और जब मैं 100k पुनरावृत्तियों से अधिक गति का परीक्षण करता हूं, तो यह पिछली प्रयुक्त विधि पर दोहरा समय का उपयोग करता है, जिसने रेगेक्स का उपयोग नहीं किया। (लेकिन 100% या तो काम कर रहे हैं)।

Testcode:

long time = System.currentTimeMillis(); 
String reg = "&(?!&#?[a-zA-Z0-9]{2,7};)"; 
String s="a regex test 1 & 2 1&2 and &_gt; - &_lt;" 
for (int i = 0; i < 100000; i++) {test=s.replaceAll(reg, "&amp;");} 
System.out.println("Finished in:" + (System.currentTimeMillis() - time) + " milliseconds"); 

तो सवाल होगा कि क्या वहाँ है अनुकूलन के कुछ स्पष्ट तरीके इस regex अभिव्यक्ति इसे और अधिक प्रभावी होने के लिए के लिए?

+0

मैं की तरह अंडरस्कोर के साथ entites लिखने के &_gt; था वरना यह प्रतीक कोड के लिए था के रूप में दिखाने चाहते हैं। – Duveit

+0

लगभग हम चारों अपने पाठ कोड प्रारूप उद्धरण के साथ ऐम्परसेंड चारों ओर संपादित करने के लिए करने की कोशिश की। बस इच्छित टेक्स्ट का चयन करें और कोड का उपयोग करें, यह एम्पर्सेंड बनाए रखेगा। – cgp

उत्तर

6

s.replaceAll(reg, "&amp;") प्रत्येक बार नियमित अभिव्यक्ति संकलित कर रहा है। पैटर्न को संकलित करने से प्रदर्शन में कुछ वृद्धि होगी (इस मामले में ~ 30%)।

long time = System.currentTimeMillis(); 
String reg = "&(?!&#?[a-zA-Z0-9]{2,7};)"; 
Pattern p = Pattern.compile(reg); 
String s="a regex test 1 & 2 1&2 and &_gt; - &_lt;"; 
for (int i = 0; i < 100000; i++) { 
    String test = p.matcher(s).replaceAll("&amp;"); 
} 
System.out.println("Finished in:" + 
      (System.currentTimeMillis() - time) + " milliseconds"); 
+0

यह सच है, यह इसे 550ms से 450ms तक नीचे चला गया। मैं देखूंगा कि क्या हम प्रीकंपिल्ड पैटर्न को कार्यान्वित कर सकते हैं। – Duveit

0

मैं जावा regex वर्गों के साथ बहुत परिचित नहीं हूँ, लेकिन सामान्य रूप में आप के लिए एक शून्य चौड़ाई अग्रदर्शी की जाँच करना चाहते हो सकता है; एम्परसैंड के बाद।

Here is a link का वर्णन सकारात्मक और नकारात्मक lookaheads

+0

यह पृष्ठ मैं जब मैं वास्तव में :) बनाया को देखकर किया गया है सकारात्मक, नकारात्मक lookaheads बनाम पर एक दृष्टि डाली, लेकिन बदलाव मैंने कोशिश की, फ्लॉप क्षमता में वृद्धि। – Duveit

1

ऐसा करने का एक और तरीका है regexp के साथ अपने सिर उड़ाने wihtout Commons Lang से StringEscapeUtils उपयोग करने के लिए किया जाएगा।

+0

हम इस पुस्तकालय के कुछ हिस्सों का उपयोग कर रहे हैं, हालांकि हमें केवल इस मामले में एम्पर्सेंड को ठीक करने की आवश्यकता है। और इसे एक स्ट्रिंग को स्वीकार करना है जो कि इकाइयों और सरल और मिश्रण का मिश्रण हो सकता है। - हालांकि धन्यवाद। – Duveit

2

आप अपने लुक-आगे जोर से & को बाहर करने के लिए है। तो यह नियमित अभिव्यक्ति की कोशिश:

&(?!#?[a-zA-Z0-9]{2,7};) 

या अधिक सटीक होना करने के लिए:

&(?!(?:#(?:[xX][0-9a-fA-F]|[0-9]+)|[a-zA-Z]+);) 
संबंधित मुद्दे