php

2010-10-15 3 views
5

में नकारात्मक दिखने और लालची क्वांटिफायर मैं किसी भी यूआरएल को खोजने और उन्हें तदनुसार जोड़ने के लिए रेगेक्स का उपयोग कर रहा हूं। हालांकि, मैं पहले से जुड़े किसी भी यूआरएल को लिंक नहीं करना चाहता हूं, इसलिए मैं यह देखने के लिए देख रहा हूं कि यूआरएल में इससे पहले एक href है या नहीं। यह विफल रहता है क्योंकि चरम लंबाई में क्वांटिफ़ायर की अनुमति नहीं है और PHP के लिए देखो।php

/\b(?<!href\s*=\s*[\'\"])((?:http:\/\/|www\.)\S*?)(?=\s|$)/i 

इस समस्या को हल का सबसे अच्छा तरीका क्या है:

यहाँ मैच के लिए regex है?

संपादित करें:

मैं अभी तक यह परीक्षण करने के लिए है, लेकिन मैं एक भी regex में यह करने के लिए चाल regex, जो PCRE द्वारा समर्थित है के भीतर सशर्त भाव उपयोग कर रहा है लगता है। यह कुछ इस तरह दिखेगा:

/(href\s*=\s*[\'\"])?(?(1)^|)((?:http:\/\/|www\.)\w[\w\d\.\/]*)(?=\s|$)/i 

प्रमुख मुद्दा यह है कि अगर href कब्जा कर लिया है, मैच तुरंत बाहर सशर्त (?(1)^|), जो मेल नहीं करने की गारंटी है की वजह से फेंक दिया जाता है। शायद इसमें कुछ गड़बड़ है। मैं कल इसका परीक्षण करूंगा।

+4

उम, एक HTML पार्सर का उपयोग करें और केवल टेक्स्ट नोड होने पर लिंक करें? – kennytm

+0

शायद यह सबसे अच्छा समाधान है। मैं यह देखने के लिए उत्सुक था कि यद्यपि रेगेक्स को समायोजित करने का कोई तरीका था या नहीं। –

+0

+1 अच्छा सवाल है। – NikiC

उत्तर

1

मैंने कोशिश की एक ही बात इसका उल्टा कर: सुनिश्चित करें कि URL "> से समाप्त नहीं होता:

/((?:http:\/\/|www\.)(?:[^"\s]|"[^>]|(*FAIL))*?)(?=\s|$)/i 

लेकिन मेरे लिए यह बहुत hacky लग रहा है, मैं तुम्हें बेहतर कर सकते हैं यकीन है।

मेरे दूसरा दृष्टिकोण अधिक तुम्हारा के समान है (और इस प्रकार अधिक सटीक है):

/href\s*=\s*"[^"]*"(*SKIP)(*FAIL)|((?:http:\/\/|www\.)\S*?)(?=\s|$)/i 

अगर मैं एक href= मैं (*SKIP)(*FAIL) पाते हैं। इसका मतलब यह है कि जब मैं (*SKIP) से मुकाबला करता हूं तो मैं रेगेक्स इंजन की स्थिति में कूद जाता हूं।

लेकिन यह कम हैकी नहीं है और मुझे यकीन है कि एक बेहतर विकल्प है।

+0

@steven_desu: यही कारण है कि मैं दूसरे संस्करण के साथ रहना होगा;) – NikiC

0

मेरे पास बेहतर रेगेक्स नहीं है। लेकिन अगर आपको बेहतर रेगेक्स नहीं मिलता है तो मैं कार्य के लिए दो प्रश्नों का उपयोग करने का सुझाव दूंगा। सबसे पहले, सभी लिंक ढूंढें और हटाएं और फिर यूआरएल खोजें। यह संभवतः आसान और तेज़ होगा। (एक बार में खोजने और बदलने के लिए, आप कुछ उपयोग कर सकते हैं - http://www.satya-weblog.com/2010/08/php-regex-find-and-replace-any-word-string-or-text-at-one-go.html)।

0

"प्रत्येक यूआरएल जो एक लिंक का हिस्सा नहीं है" ढूँढना काफी मुश्किल तर्क है। प्रत्येक यूआरएल को ढूंढना आसान हो सकता है, फिर प्रत्येक यूआरएल जो एक लिंक है, और पूर्ववर्ती सूची में से प्रत्येक को हटा दें।

जहां तक ​​खोज जो यूआरएल एक कड़ी का एक हिस्सा हैं, की कोशिश:

/<a([\s]+[\w="]+)*[\s]+href[\s]*=[\s]*"([\w\s:/.?+&=]+)"([\s]+[\w="]+)*>/i 

मुझे यकीन है कि होने के लिए http://regexpal.com/ साथ यह परीक्षण किया गया। यह <a पहले दिखता है, फिर यह किसी भी पैरामीटर के लिए अनुमति देता है, उसके बाद href, इसके बाद किसी भी अन्य पैरामीटर के बाद। अगर इसमें href नहीं है, तो यह एक लिंक नहीं है। यदि यह <a> टैग नहीं है, तो यह कोई लिंक नहीं है। चूंकि यह केवल की सूची की सूची है जो अन्य सूची (यूआरएल) से हटा दें, मैंने [\w\s:/.?+&=]+ पर एक यूआरएल की परिभाषा को सरल बना दिया। जहां तक ​​यूआरएल की एक सूची उत्पन्न होती है, आपको कुछ बेहतर चाहिए।

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