PHP: कोष्ठक के भीतर पाठ निकालने का सबसे अच्छा तरीका?


83

कोष्ठक के बीच पाठ सेट निकालने का सबसे अच्छा / सबसे कुशल तरीका क्या है? कहें कि मैं स्ट्रिंग को "पाठ" से प्राप्त करना चाहता था "संभवत: इस (पाठ) को छोड़कर" सबसे अधिक संभव तरीके से सब कुछ अनदेखा करें।

अब तक, सबसे अच्छा मैं इस के साथ आया हूँ:

$fullString = "ignore everything except this (text)";
$start = strpos('(', $fullString);
$end = strlen($fullString) - strpos(')', $fullString);

$shortString = substr($fullString, $start, $end);

क्या ऐसा करने के लिए इससे अच्छा तरीका है? मुझे पता है कि रेगेक्स का उपयोग करना सामान्य रूप से कम कुशल है, लेकिन जब तक मैं फ़ंक्शन कॉल की संख्या को कम नहीं कर सकता, शायद यह सबसे अच्छा तरीका होगा? विचार?


आपको s($fullString)->between("(", ")")मदद मिल सकती है , जैसा कि इस स्टैंडअलोन लाइब्रेरी में पाया गया है ।
caw

जवाबों:


144

मैं बस एक regex करना चाहते हैं और इसके साथ मिलता है। जब तक आप पर्याप्त पुनरावृत्तियों नहीं कर रहे हैं कि यह एक बड़ा प्रदर्शन मुद्दा बन जाता है, तो इसे कोड करना आसान है (और जब आप इसे देखते हैं तो समझें)

$text = 'ignore everything except this (text)';
preg_match('#\((.*?)\)#', $text, $match);
print $match[1];

1
नहीं, यह नहीं है:। केवल एक ही पात्र से मेल खाता है।
एडवर्ड जेड यांग

1
जरुरी नहीं, ? एक आलसी मैच है। इसके बिना, इस (पाठ) को छोड़कर (सब कुछ) को अनदेखा करने जैसा एक स्ट्रिंग, इस (पाठ) को छोड़कर मैच हमेशा के लिए खत्म हो जाएगा (पाठ)
ओवेन

1
जानकार अच्छा लगा। उन सभी चुकता नोटों से बचना चाहिए। Eg / src = "([^"] *) "/ अब इसे /src="(.*?)"/: D
Dimitry

यह अच्छा है कि आप "जब आप इसे वापस देख सकते हैं" समझ सकते हैं। इसे विफल करते हुए, आपको इसे स्पष्ट करने के लिए कुछ स्टैक ओवरफ्लो टिप्पणियां मिली हैं।
मेनेबोरिको

2
/ src = "([^"] *) "/ /src="(.*?)"/ तुलना में अधिक कुशल है
Tanj

14

तो, वास्तव में, कोड तुम्हें तैनात काम नहीं करता है: substr()'sपैरामीटर $ स्ट्रिंग, $ शुरू करने और कर रहे हैं $ लंबाई , और strpos()'sमापदंड हैं $haystack, $needle। ज़रा - सा संशोधित:

$ str = "इस (पाठ) को छोड़कर सब कुछ अनदेखा करें";
$ स्टार्ट = स्ट्रैप्स ($ str, '(');
$ end = strpos ($ str, ')', $ start + 1);
$ लंबाई = $ अंत - $ शुरुआत;
$ परिणाम = पदार्थ ($ str, $ start + 1, $ लंबाई - 1);

कुछ सूक्ष्मताएँ: मैंने दूसरे कोष्ठक पर खोज $start + 1करते समय PHP की मदद करने के लिए ऑफ़सेट पैरामीटर का उपयोग किया strpos(); हम $startएक वृद्धि $lengthकरते हैं और कोष्ठकों को मैच से बाहर करने के लिए कम करते हैं।

इसके अलावा, इस कोड में कोई त्रुटि जाँच नहीं है: आप यह सुनिश्चित करना चाहेंगे $startऔर $endप्रदर्शन करने से पहले === गलत न करें substr

strpos/substrबनाम रेगेक्स का उपयोग करने के लिए ; प्रदर्शन-वार, यह कोड एक नियमित अभिव्यक्ति को हरा देगा। हालांकि यह एक छोटा शब्द है। मैं खाना खाता हूं और सांस लेता strpos/substrहूं, इसलिए मुझे इससे ज्यादा ऐतराज नहीं है, लेकिन कोई और रेगेक्स की कॉम्पैक्टनेस पसंद कर सकता है।


1
ध्यान दें कि यदि आप $ अंत पर स्ट्रैप्स (स्ट्रिंग के पीछे से शुरू होता है) का उपयोग करने के लिए इस कोड को संशोधित करते हैं तो यह उन मामलों को सही ढंग से संभाल लेगा जहां भीतर परेंस हैं .. जैसे (अच्छी तरह से यह (बहुत) अच्छा है)।
फुटोट्रेटर

9

एक नियमित अभिव्यक्ति का उपयोग करें:

if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
    $text = $match[1];

3

यह '[' और '] के बीच के सभी पाठों को निकालने के लिए एक नमूना कोड है और इसे 2 अलग-अलग सरणियों (जैसे एक कोष्ठक में कोष्ठक के अंदर पाठ और दूसरे सरणी में कोष्ठक के बाहर का पाठ) संग्रहीत करें

   function extract_text($string)
   {
    $text_outside=array();
    $text_inside=array();
    $t="";
    for($i=0;$i<strlen($string);$i++)
    {
        if($string[$i]=='[')
        {
            $text_outside[]=$t;
            $t="";
            $t1="";
            $i++;
            while($string[$i]!=']')
            {
                $t1.=$string[$i];
                $i++;
            }
            $text_inside[] = $t1;

        }
        else {
            if($string[$i]!=']')
            $t.=$string[$i];
            else {
                continue;
            }

        }
    }
    if($t!="")
    $text_outside[]=$t;

    var_dump($text_outside);
    echo "\n\n";
    var_dump($text_inside);
  }

आउटपुट: extract_text ("आप कैसे हैं?"); उत्पादन करेंगे:

array(1) {
  [0]=>
  string(18) "hello how are you?"
}

array(0) {
}

extract_text ("हैलो [http://www.google.com/test.mp3] आप कैसे हैं?"); उत्पादन करेंगे

array(2) {
  [0]=>
  string(6) "hello "
  [1]=>
  string(13) " how are you?"
}


array(1) {
  [0]=>
  string(30) "http://www.google.com/test.mp3"
}

+1 लेकिन कैसे [* और *] के लिए एक ही है? क्योंकि [] केवल उदाहरण के लिए html पर उपयोग किया जाता है।
माइक कास्त्रो डेमरिया

1

यह फ़ंक्शन उपयोगी हो सकता है।

    public static function getStringBetween($str,$from,$to, $withFromAndTo = false)
    {
       $sub = substr($str, strpos($str,$from)+strlen($from),strlen($str));
       if ($withFromAndTo)
         return $from . substr($sub,0, strrpos($sub,$to)) . $to;
       else
         return substr($sub,0, strrpos($sub,$to));
    }
    $inputString = "ignore everything except this (text)";
    $outputString = getStringBetween($inputString, '(', ')'));
    echo $outputString; 
    //output will be test

    $outputString = getStringBetween($inputString, '(', ')', true));
    echo $outputString; 
    //output will be (test)

strpos () => जिसका उपयोग किसी स्ट्रिंग में पहले विक्षोभ की स्थिति ज्ञात करने के लिए किया जाता है।

strrpos () => जिसका उपयोग किसी स्ट्रिंग में पहले विक्षोभ की स्थिति ज्ञात करने के लिए किया जाता है।


1

पहले से ही पोस्ट किए गए रेगेक्स समाधान - \((.*?)\)और \(([^\)]+)\)- एक खुले और करीब कोष्ठक के बीच अंतर तारों को वापस नहीं करते हैं। एक स्ट्रिंग है Text (abc(xyz 123)वे दोनों वापस आ एक (abc(xyz 123)एक पूरे मैच के रूप में है, और नहीं (xyz 123)

पैटर्न जो कि सबस्ट्रिंग से मेल खाता है ( preg_matchपहले के साथ और preg_match_allसभी घटनाओं को प्राप्त करने के लिए उपयोग करें ) बीच में अन्य खुले और बंद कोष्ठक के बिना कोष्ठक में है, यदि मैच में कोष्ठक शामिल होना चाहिए:

\([^()]*\)

या, आप कोष्ठक के बिना मान प्राप्त करना चाहते हैं:

\(([^()]*)\)        // get Group 1 values after a successful call to preg_match_all, see code below
\(\K[^()]*(?=\))    // this and the one below get the values without parentheses as whole matches 
(?<=\()[^()]*(?=\)) // less efficient, not recommended

*साथ बदलें +अगर वहाँ कम से कम 1 चार के बीच (और होना चाहिए )

विवरण :

  • \( - एक प्रारंभिक दौर ब्रैकेट (एक शाब्दिक कोष्ठक को दर्शाने के लिए बच जाना चाहिए क्योंकि यह एक चरित्र वर्ग के बाहर उपयोग किया जाता है)
  • [^()]*- के अलावा और शून्य या अधिक वर्ण (इन पर ध्यान दें और इसे वर्ण वर्ग के अंदर रखने से बचना नहीं चाहिए , और इसका उपयोग किसी समूह को निर्दिष्ट करने के लिए नहीं किया जा सकता है और इसे शाब्दिक कोष्ठक के रूप में माना जाता है)()()()
  • \) - एक समापन दौर ब्रैकेट (एक शाब्दिक कोष्ठक को निरूपित करने के लिए बच जाना चाहिए क्योंकि यह एक चरित्र वर्ग के बाहर उपयोग किया जाता है)।

\(\Kएक वैकल्पिक regex मैचों में हिस्सा (मैच मूल्य से और अस्वीकार करते हैं (साथ \Kमैच रीसेट ऑपरेटर)। (?<=\()एक ऐसा पॉज़िटिव लुकबाइंड है (, जिसे वर्तमान स्थान के बाईं ओर तुरंत दिखाई देने की आवश्यकता होती है , लेकिन (मैच वैल्यू में जोड़ा नहीं जाता है क्योंकि लुकबाइंड (लुकअराउंड) पैटर्न उपभोग नहीं कर रहे हैं। (?=\()एक सकारात्मक रूपांतर है जिसे )वर्तमान स्थान के दाईं ओर दिखाई देने के लिए चार की आवश्यकता होती है ।

PHP कोड :

$fullString = 'ignore everything except this (text) and (that (text here))';
if (preg_match_all('~\(([^()]*)\)~', $fullString, $matches)) {
    print_r($matches[0]); // Get whole match values
    print_r($matches[1]); // Get Group 1 values
}

आउटपुट:

Array ( [0] => (text)  [1] => (text here) )
Array ( [0] => text    [1] => text here   )

0
function getStringsBetween($str, $start='[', $end=']', $with_from_to=true){
$arr = [];
$last_pos = 0;
$last_pos = strpos($str, $start, $last_pos);
while ($last_pos !== false) {
    $t = strpos($str, $end, $last_pos);
    $arr[] = ($with_from_to ? $start : '').substr($str, $last_pos + 1, $t - $last_pos - 1).($with_from_to ? $end : '');
    $last_pos = strpos($str, $start, $last_pos+1);
}
return $arr; }

यह पिछले उत्तर के लिए थोड़ा सुधार है जो सरणी रूप में सभी पैटर्न लौटाएगा:

getStringsBetween ('[T] उसका [] [परीक्षण] स्ट्रिंग [पैटर्न]') है:


0

मुझे लगता है कि यह एक स्ट्रिंग में पहले कोष्ठक के बीच शब्दों को प्राप्त करने का सबसे तेज़ तरीका है।

$string = 'ignore everything except this (text)';
$string = explode(')', (explode('(', $string)[1]))[0];
echo $string;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.