2017-05-09 9 views
6

पर आधारित सरणी में स्प्लिट स्ट्रिंग को विराम चिह्नों या रिक्त स्थान की उपस्थिति के आधार पर मुझे स्ट्रिंग को कई अलग-अलग भागों में विभाजित करने का एक तरीका चाहिए।रेगेक्स - विराम चिह्न/रिक्त स्थान

क्या मैं यह मतलब है कि हर शब्द का अपना सरणी तत्व में विभाजित किया जाना चाहिए, इसके अलावा विराम चिह्न जो शुरू में या शब्द के अंत पर है भी अपनी ही सरणी तत्व में रखा जाना चाहिए है।

उदाहरण के लिए: मैं (शब्द के बीच में जैसे अक्षर लोप) एक जुदाई ** संपादित का कारण नहीं होना चाहिए शब्द के बीच में तो विराम चिह्न

array(
    "Hello", 
    ", " 
    "Harry", 
    "Potter" 
    ". ", 
    "I'm", 
    "Tom", 
    "Riddle", 
    ". " 
) 

में स्ट्रिंग Hello, Harry Potter. I'm Tom Riddle. चालू करने के लिए सक्षम होना चाहिए : ** वांछित व्यवहार को स्पष्ट करने के लिए, I'm, didn't, आदि एक शब्द रहना चाहिए, लेकिन hello!, "okay, आदि प्रारंभ या अंत में विराम चिह्न से अलग किया जाना चाहिए।

इसके अलावा, विराम चिह्न जो मैं खोज में शामिल होना चाहते हैं कर रहे हैं:

  • । (पूर्ण स्टॉप/अवधि)
  • ? (प्रश्न चिह्न)
  • ! (उद्घोषणा चिह्न)
  • , (अल्पविराम)
  • ; (सेमी-कोलन)
  • : (कोलन)
  • (-) (हाइफन-डैश)
  • ((ब्रैकेट शुरू)
  • ) (अंत ब्रैकेट)
  • {(शुरू Squigly ब्रेस)
  • } (अंत Squigly ब्रेस)
  • [(वर्ग कोष्ठक शुरू)
  • ] (अंत वर्ग कोष्ठक)
  • '(एकल उद्धरण चिह्न)
  • "(दोहरा उद्धरण चिह्न)
  • ... (elpises)
निकटतम मैं परिणाम मैं जरूरत के लिए मिल गया है

यह है:

preg_split('/(\s|[\.,\/])/', $string, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 

हालांकि, इस के साथ समस्याओं कर रहे हैं:

    सामान्य विराम चिह्न के रूप में
  • विराम चिह्न मध्य शब्द मायने रखता है
  • सरणी सरणी ई युक्त तत्व पट्टे में भी जगह नहीं है। संपादित करें: अस्पष्टता के लिए खेद है; इसके द्वारा, मेरा मतलब था कि मैं विराम चिह्नों को उस स्थान को रखना चाहता था जो पंट्यूशन चिह्न के बाद/पहले है। जैसे यदि यह अल्पविराम है, तो यह , (बाद में स्थान) होगा, लेकिन यदि यह एक उद्घाटन ब्रैकेट है, तो यह ( (पहले स्थान) होगा।
  • जब मैं शेष विराम चिह्नों को जोड़ता हूं तो मुझे चाहिए (preg_split("/(\s|[\.?!,;:-(){}[]'\"…\/])/",) मुझे एक त्रुटि मिलती है।मैं बहुत यकीन है कि यह गलती से हुआ है कि कोई अनपेक्षित चरित्र के कारण कर रहा हूँ, इसलिए मैं preg_quote, जो \.\?\!,;\:\-\(\)\{\}\[\]'"… लौटे के माध्यम से है कि पूरी बात भाग गया, लेकिन यह अभी भी त्रुटि देता है: Parse error: syntax error, unexpected '…' (T_STRING), expecting ',' or ')' in [...][...] on line 5

मेरे regex की समझ काफी सीमित है, लेकिन php दस्तावेज़ों को देखने के बाद मैं इकट्ठा कर सकता हूं कि उपरोक्त कोड प्रत्येक व्हाइटस्पेस पर शब्दों को अलग करता है, या हर बार जब यह कॉमा या विराम चिह्न का सामना करता है। (अगर मैं वहां गलत हूं तो मुझे सही करें?) और जैसा कि मैंने समझा, स्क्वायर ब्रैकेट्स के भीतर बाकी वर्ण जोड़कर यह उन पात्रों में से किसी भी स्ट्रिंग को अलग कर देगा (?) चूंकि यह काम नहीं कर रहा है, मैं मान लीजिए कि यह कैसे काम करता है इसके बारे में मौलिक गलतफहमी है, इसलिए एक स्पष्टीकरण की सराहना की जाएगी।

उत्तर

1

क्या आप वास्तव में सभी शब्द-आंतरिक विराम चिह्न संलग्न रहने के लिए चाहते हैं? ऐसा लगता है कि आप प्रत्येक विराम चिह्न चरित्र को अलग से टोकननाइज़ करना चाहते हैं (लेकिन पास के व्हाइटस्पेस को संलग्न करें), जो कि अधिकांश काम है। यदि आप वास्तव में करते हैं, तो इसे करना चाहिए। काम पर दिखाने के लिए एक परीक्षण स्ट्रिंग के साथ आता है।

$string = "Hello, it's me-me-it's-me!!! o... (a friend?)"; 
print_r(preg_split("/(\w\S+\w)|(\w+)|(\s*\.{3}\s*)|(\s*[^\w\s]\s*)|\s+/", $string, 
     -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE)); 

आउटपुट:

Array 
(
    [0] => Hello 
    [1] => , 
    [2] => it's 
    [3] => me-me-it's-me 
    [4] => ! 
    [5] => ! 
    [6] => ! 
    [7] => o 
    [8] => ... 
    [9] => (
    [10] => a 
    [11] => friend 
    [12] => ? 
    [13] =>) 
) 

यह है कि यह कैसे काम करता है:

  1. (\w\S+\w) कब्जा 3+ पात्रों में से किसी भी शब्द, एम्बेडेड गैर पत्र की इजाजत दी।
  2. (\w+) किसी भी शब्द को कैप्चर करें (छोटे शब्दों को पकड़ने के लिए)।
  3. (\s*\.{3}\s*) किसी भी आसपास के स्थान के साथ, इलिप्सिस ... कैप्चर करें।
  4. (\s*[^\w\s]\s*) व्यक्तिगत रूप से किसी गैर-अक्षर, गैर-स्पेस वर्णों को कैप्चर करें; लेकिन किसी भी आस-पास की जगह संलग्न करें।
  5. \s+ कोई अन्य रिक्त स्थान (यानी, शब्दों के बीच) स्ट्रिंग को विभाजित करता है, लेकिन पर कब्जा नहीं किया गया है।

आप क्या एक शब्द के अंदर हो सकता है, क्या आप अनुमति देना चाहते की एक सूची के साथ पहले विकल्प में \S+ की जगह, उदाहरण के लिए, [\w'-]+ अक्षर लोप और हाइफ़न केवल अनुमति देने के लिए के बारे में चयनात्मक होना चाहते हैं।

+0

प्रतिक्रिया के लिए बहुत बहुत धन्यवाद; जो संख्या 4 में आप वर्णन करते हैं वह काम नहीं कर रहा है, या शायद आपने मेरे प्रश्न को गलत समझा है (माफ करना अगर यह खराब शब्द है)। https://gyazo.com/2db04904b5f9a5c9d06a7986c507b057 कॉमा के बाद एक जगह होने के लिए मेरा इच्छित परिणाम क्या था, इसलिए 2 '", "' 'होगा। यदि यह संभव नहीं है, तो क्या सरणी में रिक्त स्थान भी वापस करना संभव है ताकि मैं इसके माध्यम से लूप कर सकूं और इसे इस तरह कुशल बना सकूं? –

+0

वास्तव में उस अंतिम टिप्पणी को अनदेखा करें, मेरे कोड को देखते हुए, मुझे लगता है कि वहां केवल अपने तत्वों के रूप में रिक्त स्थान होना आसान होगा (इसलिए वहां एक सरणी तत्व होगा जिसमें केवल एक ही स्थान होगा)। क्या कोड को ऐसा करना संभव है? –

+0

ओह, अगर मैं 'var_dump()' का उपयोग करता तो भी मैं त्रुटि पकड़ा होता। वास्तव में यह माना जाता था कि अल्पविराम के साथ अंतरिक्ष को पकड़ना था, अभी तक यह सुनिश्चित नहीं है कि मैंने क्या गलत किया है। लेकिन मैं उम्मीद कर रहा था कि आप देखेंगे कि यह दृष्टिकोण कैसे काम करता है और जो भी आप वास्तव में चाहते हैं उसे ट्विक करने में सक्षम हो (जो अभी भी पूरी तरह से स्पष्ट नहीं है, हालांकि आपकी मूल - मूलताओं की यह पहलू थी)। – alexis

5

यह करना होगा, फिर भी उत्पादन इतना I'm विभाजित किया जाएगा थोड़ा अलग रूप में आप ' एक चरित्र के रूप में शामिल पर विभाजित करने के लिए है,:

$result = preg_split('/(\.\.\.\s?|[-.?!,;:(){}\[\]\'"]\s?)|\s/', 
        $string, null, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); 

यह सरल किया जा सकता है, लेकिन मैं सिर्फ दीर्घवृत्त शामिल ... एक वैकल्पिक स्थान या वैकल्पिक स्थान या एक स्थान के साथ आपके सभी अन्य पात्रों के साथ।

आप, डॉट्स चरित्र वर्ग [] की . बाहर भागने [ और ] चरित्र वर्ग और - जरूरतों के अंदर भाग निकले किए जाने से बचने या पहले आओ या तो के रूप में एक सीमा निरूपित करने के लिए नहीं पिछले की जरूरत है। स्पष्ट रूप से आपको उस उद्धरण से बचने की आवश्यकता है जिसका उपयोग आप पैटर्न को रखने के लिए करते हैं, इस मामले में एकल '

आप निर्दिष्ट नहीं किया है एक अंतरिक्ष विराम चिह्न के दोनों तरफ की आवश्यकता है और यह स्पष्ट नहीं है कि अगर यह "सामान्य विराम चिह्न के रूप में विराम चिह्न मध्य शब्द मायने रखता है" का अर्थ यह होना चाहिए या गिनती नहीं करना चाहिए।

+0

हाहा एक प्रश्न पूछने वाला था, लेकिन मुझे लगता है कि आपने इसे संपादित किया है: पी बहुत बहुत धन्यवाद, यह अच्छी तरह से काम करता है :) क्या मैं सिर्फ पूछ सकता हूं कि क्यों वर्णों के बीच में आने वाले परिणामों को बाहर करने का कोई तरीका नहीं है ? जब मैं इसे स्वयं हल करने की कोशिश कर रहा था, मैंने सोचा कि मैं शायद ऐसे उदाहरणों को बाहर करने के लिए '^' का उपयोग कर सकता हूं, लेकिन मुझे ऐसा करने का कोई तरीका नहीं मिला। क्या मैंने गलत समझा कि नकारात्मकता कैसे काम करती है? –

+0

अंतिम अनुच्छेद संपादित किया गया। – AbraCadaver

+0

अस्पष्टता के लिए खेद है; मैंने वांछित व्यवहार को स्पष्ट करने के लिए प्रश्न को अद्यतन किया। –

0

सामान्य तौर पर आप उदाहरण के लिए पैटर्न

word character+[all your punctuation characters here]+word character(*SKIP)(*FAIL) 

इस्तेमाल कर सकते हैं:

\w[\[\].?\"\']\w(*SKIP)(*FAIL)|[\[\].?\"\'] 

a demo on regex101.com देखें।

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