2011-01-21 15 views
5

मेरे पास एक लाटेक्स दस्तावेज़ है जिसे मैं मिलान करना चाहता हूं। और मुझे एक रेगेक्स मैच चाहिए जो निम्नलिखित से मेल खाता है:PHP में नियमित अभिव्यक्तियों का उपयोग करके मैं नेस्टेड ब्रेसिज़ से कैसे मेल करूं?

\ # the backslash in the beginning 
[a-zA-Z]+ #a word 
(\{.+\})* # any amount of {something} 

हालांकि, और वह पकड़ है;

अंतिम पंक्ति में, यह 1. जरूरतों लालची होने के लिए और 2 की जरूरत है {} ही अंदर का मिलान संख्या है।

मतलब अगर मेरे पास स्ट्रिंग \test{something\somthing{9}} है तो यह पूरी तरह मेल खाएगा। और इसे उस क्रम में होना चाहिए ({})। इतना है कि यह निम्न से मेल नहीं खाता: \ टेक्स {} के लिए

\ LaTeX {} है एक दस्तावेज तैयार करने की प्रणाली

सिर्फ

\ LaTeX {}

और

\ TeX {}

किसी की भी सहायता करें? शायद किसी के पास मिलान के लिए एक बेहतर विचार है? क्या मुझे नियमित अभिव्यक्तियों का उपयोग नहीं करना चाहिए?

+2

यह एक नियमित रूप से बात आप मिलान कराना चाहते नहीं है, तो नियमित अभिव्यक्ति नहीं हैं बेहतर चयन। ऐसा कहा जा रहा है, आप * कर सकते हैं, क्योंकि अधिकांश नियमित अभिव्यक्ति इंजन इन दिनों नियमित नहीं होते हैं, लेकिन यह अभी भी एक अच्छा विचार नहीं है। –

+0

यदि मेरे पास कोई अन्य विकल्प था तो मैं इसके लिए जाता। लेकिन मुझे किसी अन्य चीज के बारे में पता नहीं है जिसका मैं उपयोग कर सकता हूं। क्या आपके पास कोई धोखेबाज विचार है? यदि नहीं, ऐसा लगता है कि मैं चौड़ाई रेजएक्स फंस गया हूँ। – Knarf

+0

यह न केवल '{' और '}' (जो आप रेगेक्स के साथ कर सकते हैं) की एक संख्या भी है, लेकिन आप यह भी सुनिश्चित करना चाहते हैं कि {}} {{'अस्वीकार कर दिया गया है (' '' की समान राशि है और '}'!), और जब आप टिप्पणी-रेखाओं में होते हैं तो आप '{' और '} 'को त्यागना चाहते हैं। संक्षेप में: रेगेक्स इसके लिए उपयुक्त नहीं है। –

उत्तर

2

यह प्रत्यावर्तन के साथ किया जा सकता है:

$input = "\LaTeX{} is a document preparation system for the \TeX{} 
\latex{something\somthing{9}}"; 

preg_match_all('~(?<token> 
     \\\\ # the slash in the beginning 
     [a-zA-Z]+ #a word 
     (\{[^{}]*((?P>token)[^{}]*)?\}) # {something} 
)~x', $input, $matches); 

यह सही ढंग से \LaTeX{}, \TeX{}, और \latex{something\somthing{9}}

-1

दुर्भाग्यवश, मेरा मानना ​​है कि यह असंभव है। ब्रैकेट मिलान (सही ढंग से जोड़ा गया, नेस्टेड ब्रैकेट का पता लगाना) आमतौर पर एक समस्या के उदाहरण के रूप में प्रयोग किया जाता है जिसे एक नियमित राज्य मशीन, जैसे एक नियमित अभिव्यक्ति पार्सर के साथ हल नहीं किया जा सकता है। आप इसे एक संदर्भ मुक्त व्याकरण के साथ कर सकते हैं, लेकिन यह सिर्फ रेगेक्स काम नहीं करता है। आपका सबसे अच्छा समाधान प्रारंभिक जांच के लिए {*[^{}]*}* जैसे रेगेक्स का उपयोग करना है, और फिर यह जांचने के लिए एक और छोटी स्क्रिप्ट है कि यह एक संख्या भी है या नहीं।

अंत में: कोशिश करते हैं और केवल regex के साथ यह मत करो। यह एक समस्या नहीं है जिसे अकेले रेगेक्स के साथ हल किया जा सकता है।

2

पीएचपी इस्तेमाल किया जा सकता से मेल खाता है, क्योंकि यह पुनरावर्ती regex मिलान का समर्थन करता है। लेकिन, जैसा कि मैंने कहा, अगर आप अपने LaTeX की तरह तार में टिप्पणी { या } उन में हो सकता है, इस असफल हो जायेगी।

एक डेमो:

$text = 'This is a \LaTeX{ foo { bar { ... } baz test {} done } } document 
preparation system for the \TeX{a{b{c}d}e{f}g{h}i}-y people out there'; 
preg_match_all('/\\\\[A-Za-z]+(\{(?:[^{}]|(?1))*})/', $text, $matches, PREG_SET_ORDER); 
print_r($matches); 

जो पैदा करता है:

Array 
(
    [0] => Array 
     (
      [0] => \LaTeX{ foo { bar { ... } baz test {} done } } 
      [1] => { foo { bar { ... } baz test {} done } } 
     ) 

    [1] => Array 
     (
      [0] => \TeX{a{b{c}d}e{f}g{h}i} 
      [1] => {a{b{c}d}e{f}g{h}i} 
     ) 

) 

एक त्वरित विवरण:

\\\\   # the literal '\' 
[A-Za-z]+ # one or more letters 
(   # start capture group 1 <-----------------+ 
    \{   # the literal '{'       | 
    (?:  # start non-capture group A    | 
    [^{}] #  any character other than '{' and '}' | 
    |  #  OR         | 
    (?1)  #  recursively match capture group 1 ---+ 
)   # end non-capture group A 
    *   # non-capture group A zero or more times 
    }   # the literal '}' 
)   # end capture group 1 
संबंधित मुद्दे

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