2009-11-12 11 views
7

मुझे रिक्त स्थान से स्ट्रिंग को विभाजित करने की आवश्यकता है, लेकिन उद्धरणों में वाक्यांश को अव्यवस्थित संरक्षित किया जाना चाहिए। उदाहरण:उद्धरणों के बीच वाले लोगों को छोड़कर मैं सभी सफेद जगहों को कैसे ढूंढ सकता हूं?

word1 word2 "this is a phrase" word3 word4 "this is a second phrase" word5 

इस preg_split के बाद सरणी में परिणाम चाहिए:

array(
[0] => 'word1', 
[1] => 'word2', 
[2] => 'this is a phrase', 
[3] => 'word3', 
[4] => 'word4', 
[5] => 'this is a second phrase', 
[6] => 'word5' 
) 

मैं अपने regexp कैसे रचना करने के लिए करना चाहिए?

पीएस। related question है, लेकिन मुझे नहीं लगता कि यह मेरे मामले में काम करता है। स्वीकृत उत्तर सफेद जगहों के बजाय शब्दों को खोजने के लिए regexp प्रदान करता है।

+0

यह संबंधित प्रश्न आपको जो उदाहरण देना है, उसके आधार पर आप जो करना चाहते हैं, वही दिखता है। क्या आपने उस स्वीकार्य उत्तर का प्रयास किया? क्या हुआ? – richsage

+0

हाँ, मैंने कोशिश की। मैं php का उपयोग करता हूं, नहीं .NET। मैं regexp परिणामों की इनलाइन फ़िल्टरिंग का उपयोग नहीं कर सकता। और, जैसा कि मैंने कहा, \ w + | "[\ w \ s] *" मेरे लिए काम नहीं करता है – altern

उत्तर

8

(#regex irc चैनल से उपयोगकर्ता MizardX की मदद irc.freenode.net के साथ: फिर भी, यहाँ एक और तरीका है) समाधान मिला था। यह एकल उद्धरणों का भी समर्थन करता है।

$str= 'word1 word2 \'this is a phrase\' word3 word4 "this is a second phrase" word5 word1 word2 "this is a phrase" word3 word4 "this is a second phrase" word5'; 

$regexp = '/\G(?:"[^"]*"|\'[^\']*\'|[^"\'\s]+)*\K\s+/'; 

$arr = preg_split($regexp, $str); 

print_r($arr); 

परिणाम है:

Array (
    [0] => word1 
    [1] => word2 
    [2] => 'this is a phrase' 
    [3] => word3 
    [4] => word4 
    [5] => "this is a second phrase" 
    [6] => word5 
    [7] => word1 
    [8] => word2 
    [9] => "this is a phrase" 
    [10] => word3 
    [11] => word4 
    [12] => "this is a second phrase" 
    [13] => word5 
) 

पी एस। केवल नुकसान यह है कि यह regexp केवल पीसीआरई 7 के लिए काम करता है।

यह पता चला कि मेरे पास उत्पादन सर्वर पर पीसीआरई 7 समर्थन नहीं है, केवल पीसीआरई 6 स्थापित है। भले ही यह PCRE 7 के लिए पिछले एक, regexp कि काम करेगा (\ जी और \ कश्मीर से छुटकारा मिला) के रूप में के रूप में लचीला नहीं है:

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

दिए गए इनपुट परिणाम के लिए ऊपर के समान है।

+0

\ G और \ K के लिए क्या खड़ा है? – Amarghosh

+1

'\ G' उस मैच के लिए मैच को एंकर करता है जहां पिछला मैच समाप्त होता है (मोटे तौर पर बोल रहा है), या यदि कोई पिछला मैच नहीं था तो इनपुट की शुरुआत में। '\ K' मुझे देखना था: इसका मतलब है" मैच वास्तव में यहां शुरू हुआ है "; हालांकि रेगेक्स एक टोकन और व्हाइटस्पेस से मेल खाता है, यह ऐसा करता है जैसे यह केवल व्हाइटस्पेस से मेल खाता है। एक गरीब व्यक्ति की तरफ से छेड़छाड़ की तरह, ऐसा लगता है कि ज्यादातर मामलों में यह देखने के लिए बेहतर होगा। यह सुविधा अधिक आम क्यों नहीं है, मुझे आश्चर्य है? http://www.pcre.org/pcre.txt –

+0

धन्यवाद एलन। Regex.info दोनों में नहीं मिल सका ... और regex के लिए Google के लिए यह बहुत मुश्किल है। – Amarghosh

0

मानते हैं कि आपके उद्धरण अच्छी तरह से परिभाषित हैं, यानी, जोड़ों में, आप विस्फोट कर सकते हैं और हर 2 फ़ील्ड लूप के लिए जा सकते हैं। जैसे

$str = "word1 word2 \"this is a phrase\" word3 word4 \"this is a second phrase\" word5 word6 \"lastword\""; 
print $str ."\n"; 
$s = explode('"',$str); 
for($i=1;$i<count($s);$i+=2){ 
    if (strpos($s[$i] ," ")!==FALSE) { 
     print "Spaces found: $s[$i]\n"; 
    } 
} 

उत्पादन

$ php test.php 
Spaces found: this is a phrase 
Spaces found: this is a second phrase 

कोई जटिल regexp की आवश्यकता है।

+0

निश्चित बात यह है कि मैं regexp के बिना ऐसा कर सकता हूं, लेकिन यह मेरा मामला नहीं है। – altern

0

आपके द्वारा लिंक किए गए दूसरे प्रश्न से रेगेक्स का उपयोग करना इतना आसान है?

<?php 

$string = 'word1 word2 "this is a phrase" word3 word4 "this is a second phrase" word5'; 

preg_match_all('/(\w+|"[\w\s]*")+/' , $string , $matches); 

print_r($matches[1]); 

?> 

उत्पादन:

Array 
(
    [0] => word1 
    [1] => word2 
    [2] => "this is a phrase" 
    [3] => word3 
    [4] => word4 
    [5] => "this is a second phrase" 
    [6] => word5 
) 
+0

विशेष चरित्र (उदाहरण के लिए एम्परसैंड) के बारे में क्या भी पाया जाना चाहिए? और न केवल ampersand unhandled होगा।इसके अलावा, अलग-अलग प्रतीकों को अलग-अलग संभाला जाना चाहिए। उदाहरण के लिए, यदि ब्रेसिज़ का सामना करना पड़ा, तो मुझे उन खोज परिणामों में शामिल करने की आवश्यकता है। – altern

+1

@altern, ठीक है, मुझे यकीन है कि 'edds' को कोई फर्क नहीं पड़ता कि आप अपनी आवश्यकताओं के लिए अपना उदाहरण समायोजित करें ... –

0

किसी बेंचमार्क tokenizing बनाम regex करना चाहते हैं? मेरा अनुमान है कि विस्फोट() फ़ंक्शन किसी भी गति लाभ के लिए थोड़ा बहुत भारी है।

(संपादित क्योंकि मैं उद्धृत स्ट्रिंग के भंडारण के लिए किसी और मामले में भूल गया)

$str = 'word1 word2 "this is a phrase" word3 word4 "this is a second phrase" word5'; 

// initialize storage array 
$arr = array(); 
// initialize count 
$count = 0; 
// split on quote 
$tok = strtok($str, '"'); 
while ($tok !== false) { 
    // even operations not in quotes 
    $arr = ($count % 2 == 0) ? 
           array_merge($arr, explode(' ', trim($tok))) : 
           array_merge($arr, array(trim($tok))); 
    $tok = strtok('"'); 
    ++$count; 
} 

// output results 
var_dump($arr); 
0
$test = 'word1 word2 "this is a phrase" word3 word4 "this is a second phrase" word5'; 
preg_match_all('/([^"\s]+)|("([^"]+)")/', $test, $matches); 
संबंधित मुद्दे

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