दिलचस्प पोस्ट
"आयात" के बाद "स्थिर" संशोधक क्या होता है? Genymotion डिवाइस शुरू करने में सक्षम नहीं एंड्रॉइड पर कैमरे के साथ तस्वीरें प्रोग्राम करना JSF 2 एप्लिकेशन में डिफ़ॉल्ट प्रबंधित बीन स्कोप क्या है? वैश्विक चर सूत्र में फ्लास्क सुरक्षित हैं? JFrame आइकन कैसे परिवर्तित करें रंगीन रूबी आउटपुट आईओसी कंटेनर्स का उपयोग; विशेष रूप से विंडसर दो भौगोलिक बिंदुओं के बीच दूरी प्राप्त करें क्या मैं गैर मौजूदा सीएसएस वर्गों का उपयोग कर सकता हूँ? पर्ल रेगुलर एक्सप्रेशंस को दृश्य को बिटमैप में कैसे रूपांतरित करना है? एक सरणी के लिए अभिविन्यास स्टोर – और तुलना करें संख्या ढूँढें जो सरणी में एन के बराबर या बराबर है अधिकतर अरबी पाठ वाले वेब पेज के लिए मुझे किस एन्कोडिंग का उपयोग करना चाहिए? क्या utf-8 ठीक है?

टेक्स्ट यूआरएल को कैसे बदलें और एचटीएमएल टैग्स में यूआरएल को बाहर कैसे करें?

मुझे आपकी मदद की ज़रूरत है यहाँ।

मैं इसे चालू करना चाहता हूं:

sometext sometext http://www.somedomain.com/index.html sometext sometext 

में:

 sometext sometext <a href="http://somedoamai.com/index.html">www.somedomain.com/index.html</a> sometext sometext 

मैंने इसे इस regex का उपयोग करके प्रबंधित किया है:

 preg_replace("#((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)#ie", "'<a href=\"$1\" target=\"_blank\">$1</a>$4'", $text); 

समस्या यह है कि यह img यूआरएल की जगह है, उदाहरण के लिए:

 sometext sometext <img src="http//domain.com/image.jpg"> sometext sometext 

में बदल गया है:

 sometext sometext <img src="<a href="http//domain.com/image.jpg">domain.com/image.jpg</a>"> sometext sometext 

कृपया मदद करे।

Solutions Collecting From Web of "टेक्स्ट यूआरएल को कैसे बदलें और एचटीएमएल टैग्स में यूआरएल को बाहर कैसे करें?"

Gumbo के ऊपर के सुव्यवस्थित संस्करण:

 $html = <<< HTML <html> <body> <p> This is a text with a <a href="http://example.com/1">link</a> and another <a href="http://example.com/2">http://example.com/2</a> and also another http://example.com with the latter being the only one that should be replaced. There is also images in this text, like <img src="http://example.com/foo"/> but these should not be replaced either. In fact, only URLs in text that is no a descendant of an anchor element should be converted to a link. </p> </body> </html> HTML; 

चलिए एक XPath का उपयोग करें जो कि वास्तव में उन तत्वों को प्राप्त करता है जो कि वास्तव में http: // या https: // या ftp: // वाले पाठ नं हैं और जो स्वयं एंकर तत्वों के पाठनोड नहीं हैं।

 $dom = new DOMDocument; $dom->loadHTML($html); $xPath = new DOMXPath($dom); $texts = $xPath->query( '/html/body//text()[ not(ancestor::a) and ( contains(.,"http://") or contains(.,"https://") or contains(.,"ftp://") )]' ); 

ऊपर XPath हमें निम्न डेटा के साथ एक TextNode देगा:

  and also another http://example.com with the latter being the only one that should be replaced. There is also images in this text, like 

PHP5.3 के बाद से हम XPath में PHP का उपयोग करने के लिए तीन कॉल करने के बजाय हमारे नोड्स का चयन करने के लिए रेगेक्स पैटर्न का उपयोग कर सकते हैं।

मानकों के अनुरूप पाठनों को अलग करने के बजाय, हम एक दस्तावेज़ के टुकड़े का उपयोग करेंगे और टुकड़े के साथ संपूर्ण पाठ-नोड को बदल देंगे। इस मामले में गैर-मानक केवल इसका मतलब है, जिस विधि का हम इसका उपयोग करेंगे , वह डॉम एपीआई के डब्ल्यू 3 सी विनिर्देशन का हिस्सा नहीं है ।

 foreach ($texts as $text) { $fragment = $dom->createDocumentFragment(); $fragment->appendXML( preg_replace( "~((?:http|https|ftp)://(?:\S*?\.\S*?))(?=\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)~i", '<a href="$1">$1</a>', $text->data ) ); $text->parentNode->replaceChild($fragment, $text); } echo $dom->saveXML($dom->documentElement); 

और यह तब आउटपुट होगा:

 <html><body> <p> This is a text with a <a href="http://example.com/1">link</a> and another <a href="http://example.com/2">http://example.com/2</a> and also another <a href="http://example.com">http://example.com</a> with the latter being the only one that should be replaced. There is also images in this text, like <img src="http://example.com/foo"/> but these should not be replaced either. In fact, only URLs in text that is no a descendant of an anchor element should be converted to a link. </p> </body></html> 

आपको नियमित अभिव्यक्ति के साथ ऐसा नहीं करना चाहिए – कम से कम केवल नियमित अभिव्यक्ति नहीं किसी उचित HTML DOM पार्सर का उपयोग करें, जैसे कि PHP के DOM लाइब्रेरी में से एक। फिर आप नोड्स को पुनरावृति कर सकते हैं, जांच लें कि क्या यह एक पाठ नोड है और नियमित अभिव्यक्ति की खोज करें और टेक्स्ट नोड को उचित रूप से बदलें

ऐसा कुछ ऐसा करना चाहिए:

 $pattern = "~((?:http|https|ftp)://(?:\S*?\.\S*?))(?=\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)~i"; $doc = new DOMDocument(); $doc->loadHTML($str); // for every element in the document foreach ($doc->getElementsByTagName('*') as $elem) { // for every child node in each element foreach ($elem->childNodes as $node) { if ($node->nodeType === XML_TEXT_NODE) { // split the text content to get an array of 1+2*n elements for n URLs in it $parts = preg_split($pattern, $node->nodeValue, -1, PREG_SPLIT_DELIM_CAPTURE); $n = count($parts); if ($n > 1) { $parentNode = $node->parentNode; // insert for each pair of non-URL/URL parts one DOMText and DOMElement node before the original DOMText node for ($i=1; $i<$n; $i+=2) { $a = $doc->createElement('a'); $a->setAttribute('href', $parts[$i]); $a->setAttribute('target', '_blank'); $a->appendChild($doc->createTextNode($parts[$i])); $parentNode->insertBefore($doc->createTextNode($parts[$i-1]), $node); $parentNode->insertBefore($a, $node); } // insert the last part before the original DOMText node $parentNode->insertBefore($doc->createTextNode($parts[$i-1]), $node); // remove the original DOMText node $node->parentNode->removeChild($node); } } } } 

ठीक है, चूंकि डोमोनोडेस्ट्स ऑफ एएलीमेंट्स बायटैग_नाम और चाइल्ड नोड्स लाइव हैं , डोम में हर परिवर्तन उस सूची से परिलक्षित होता है और इस प्रकार आप अग्रग्राम उपयोग नहीं कर सकते हैं जो नये जोड़े गए नोड्स को पुनरावृत्त करेगा। इसके बजाय, आपको इसके बजाय लूपों के लिए उपयोग करने की आवश्यकता होती है और इंडेक्स पॉइंटर्स बढ़ाने के लिए और सर्वोत्तम प्री-परिकलित सरंक्षण सीमाओं पर उचित तत्वों का ट्रैक रखें।

लेकिन जब से इस तरह के एलेगोरिदम में किसी भी प्रकार के जटिल एल्गोरिदम (आपको एक इंडेक्स पॉइंटर और तीन में से प्रत्येक के लिए सरणी सीमा की आवश्यकता होती है), for एक पुनरावर्ती एल्गोरिदम का उपयोग करना अधिक सुविधाजनक होता है:

 function mapOntoTextNodes(DOMNode $node, $callback) { if ($node->nodeType === XML_TEXT_NODE) { return $callback($node); } for ($i=0, $n=count($node->childNodes); $i<$n; ++$i) { $nodesChanged = 0; switch ($node->childNodes->item($i)->nodeType) { case XML_ELEMENT_NODE: $nodesChanged = mapOntoTextNodes($node->childNodes->item($i), $callback); break; case XML_TEXT_NODE: $nodesChanged = $callback($node->childNodes->item($i)); break; } if ($nodesChanged !== 0) { $n += $nodesChanged; $i += $nodesChanged; } } } function foo(DOMText $node) { $pattern = "~((?:http|https|ftp)://(?:\S*?\.\S*?))(?=\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)~i"; $parts = preg_split($pattern, $node->nodeValue, -1, PREG_SPLIT_DELIM_CAPTURE); $n = count($parts); if ($n > 1) { $parentNode = $node->parentNode; $doc = $node->ownerDocument; for ($i=1; $i<$n; $i+=2) { $a = $doc->createElement('a'); $a->setAttribute('href', $parts[$i]); $a->setAttribute('target', '_blank'); $a->appendChild($doc->createTextNode($parts[$i])); $parentNode->insertBefore($doc->createTextNode($parts[$i-1]), $node); $parentNode->insertBefore($a, $node); } $parentNode->insertBefore($doc->createTextNode($parts[$i-1]), $node); $parentNode->removeChild($node); } return $n-1; } $str = '<div>sometext http://www.somedomain.com/index.html sometext <img src="http//domain.com/image.jpg"> sometext sometext</div>'; $doc = new DOMDocument(); $doc->loadHTML($str); $elems = $doc->getElementsByTagName('body'); mapOntoTextNodes($elems->item(0), 'foo'); 

यहां mapOntoTextNodes नोड्स को एक DOM दस्तावेज़ में प्रत्येक DOMText नोड पर दिए गए कॉलबैक फ़ंक्शन को मैप करने के लिए उपयोग किया जाता है। आप या तो पूरे DOMDocument नोड या सिर्फ एक विशिष्ट डोमोड (इस मामले में सिर्फ BODY नोड) पास कर सकते हैं।

preg_split का उपयोग preg_split नोड की सामग्री में सादा यूआरएल को खोजने के लिए किया जाता है और सामग्री स्ट्रिंग को गैर-यूआरएल / यूआरएल भागों में preg_split का उपयोग करते हुए preg_split करते हुए प्रयोग किया जाता है, जबकि 1 + 2 · n वस्तुओं की एक सरणी । फिर गैर-यूआरएल भागों को नए डोमटेक्स्ट नोड्स से बदल दिया जाता है और यूआरएल भागों को नए A तत्वों द्वारा बदल दिया जाता है, जो तब मूल DOMText नोड से पहले सम्मिलित किए जाते हैं जो तब अंत में हटा दिए जाते हैं। चूंकि यह mapOntoTextNodes पुनरावर्ती रूप से चलता है, यह केवल एक विशिष्ट mapOntoTextNodes पर उस फ़ंक्शन को कॉल करने के लिए पर्याप्त होता है।

उत्तर के लिए धन्यवाद, लेकिन यह अभी भी काम करता है मैंने इस फ़ंक्शन का उपयोग करके तय किया है:

 function livelinked ($text){ preg_match_all("#((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)|^(jpg)#ie", $text, $ccs); foreach ($ccs[3] as $cc) { if (strpos($cc,"jpg")==false && strpos($cc,"gif")==false && strpos($cc,"png")==false ) { $old[] = "http://".$cc; $new[] = '<a href="http://'.$cc.'" target="_blank">'.$cc.'</a>'; } } return str_replace($old,$new,$text); } 

यदि आप एक regex (और इस मामले में, एक regex काफी उपयुक्त है) का उपयोग करना चाहते हैं, तो आप regex मैच केवल यूआरएल हो सकते हैं जो "अकेले खड़े हैं" एक शब्द सीमा से बचने के अनुक्रम ( \b ) का उपयोग करके, आप केवल regex मैच प्राप्त कर सकते हैं जहां http तुरंत सफेद स्थान या पाठ की शुरुआत से पहले होती है:

 preg_replace("#\b((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)#ie", "'<a href=\"$1\" target=\"_blank\">$1</a>$4'", $text); // ^^ thar she blows 

इस प्रकार, "http://..." से मेल नहीं खाएगा, लेकिन http:// जैसा कि अपना स्वयं का शब्द होगा

DomDocument अधिक परिपक्व है और बहुत तेज चलता है, इसलिए यह सिर्फ एक विकल्प है यदि कोई भी PHP सरल HTML DOM Parser का उपयोग करना चाहता है:

 <?php require_once('simple_html_dom.php'); $html = str_get_html('sometext sometext http://www.somedomain.com/index.html sometext sometext <a href="http://www.somedomain.com/index.html">http://www.somedomain.com/index.html</a> sometext sometext <img src="http//domain.com/image.jpg"> sometext sometext'); foreach ($html->find('text') as $element) { // you can add any tag into the array to exclude from replace if (!in_array($element->parent()->tag, array('a'))) $element->innertext = preg_replace("#((http|https|ftp)://(\S*?\.\S*?))(\s|\;|\)|\]|\[|\{|\}|,|\"|'|:|\<|$|\.\s)#ie", "'<a href=\"$1\" target=\"_blank\">$1</a>$4'", $element->innertext); } echo $html; 

आप इस प्रश्न से अपना कोड आज़मा सकते हैं:

 echo preg_replace('/<a href="([^"]*)([^<\/]*)<\/a>/i', "$1", 'sometext sometext <img src="http//domain.com/image.jpg"> sometext sometext'); 

यदि आप कुछ अन्य टैग बदलना चाहते हैं – यह इतना आसान है:

 echo preg_replace('/<img src="([^"]*)([^\/><]*)>/i', "$1", 'sometext sometext <img src="http//domain.com/image.jpg"> sometext sometext'); 

url स्ट्रिंग के प्रारंभ और अंत में एक सफेद स्थान (\ s) से मेल खाती है, यह सुनिश्चित करेगा कि

 "http://url.com" 

द्वारा मिलान नहीं किया गया है

 http://url.com 

मेल खाता है;