संभवतः मुख्य चीज जो इसे फेंक रही है वह \s
क्षैतिज और ऊर्ध्वाधर स्थान से मेल खाती है। बस क्षैतिज स्थान, उपयोग मिलान करने के लिए \h
, और बस खड़ी अंतरिक्ष मिलान करने के लिए, \v
।
एक छोटी सी सिफारिश जो मैं करता हूं वह है टोकन में नए सिरे को शामिल करना। आप वैकल्पिक ऑपरेटरों का उपयोग करना चाहते हैं %
या %%
, जैसा कि वे इस प्रकार के काम को संभालने के लिए डिज़ाइन किए गए हैं:
grammar Parser {
token TOP {
<headerRow> \n
<valueRow>+ %% \n
}
token headerRow { <.ws>* %% <header> }
token valueRow { <.ws>* %% <value> }
token header { \S+ }
token value { \S+ }
token ws { \h* }
}
इसके लिए परिणाम Parser.parse($dat)
निम्न है:
「ID Name Email
1 test test@email.com
321 stan stan@nowhere.net
」
headerRow => 「ID Name Email」
header => 「ID」
header => 「Name」
header => 「Email」
valueRow => 「 1 test test@email.com」
value => 「1」
value => 「test」
value => 「test@email.com」
valueRow => 「 321 stan stan@nowhere.net」
value => 「321」
value => 「stan」
value => 「stan@nowhere.net」
valueRow => 「」
जो हमें दिखाता है कि व्याकरण ने हर चीज को सफलतापूर्वक पार कर लिया है। हालाँकि, अपने प्रश्न के दूसरे भाग पर ध्यान केंद्रित करें, कि आप इसे अपने लिए एक चर में उपलब्ध कराना चाहते हैं। ऐसा करने के लिए, आपको एक एक्शन क्लास की आपूर्ति करनी होगी जो इस परियोजना के लिए बहुत सरल है। आप बस एक ऐसा वर्ग बनाते हैं, जिसके तरीके आपके व्याकरण के तरीकों से मेल खाते हैं (हालाँकि बहुत ही सरल, जैसे value
/ header
जिन्हें विशेष प्रक्रिया की आवश्यकता नहीं है, इसके अलावा, उन्हें अनदेखा किया जा सकता है)। आपके प्रसंस्करण को संभालने के लिए कुछ और रचनात्मक / कॉम्पैक्ट तरीके हैं, लेकिन मैं चित्रण के लिए काफी रूढ़िवादी दृष्टिकोण के साथ जाऊंगा। यहाँ हमारी कक्षा है:
class ParserActions {
method headerRow ($/) { ... }
method valueRow ($/) { ... }
method TOP ($/) { ... }
}
प्रत्येक विधि में हस्ताक्षर हैं ($/)
जो रेगेक्स मैच चर है। तो अब, आइए पूछें कि हम प्रत्येक टोकन से क्या जानकारी चाहते हैं। हेडर पंक्ति में, हम प्रत्येक हेडर मान को एक पंक्ति में चाहते हैं। इसलिए:
method headerRow ($/) {
my @headers = $<header>.map: *.Str
make @headers;
}
उस पर एक परिमाणक के साथ कोई टोकन एक माना जाएगा Positional
, तो हम भी साथ प्रत्येक व्यक्ति के हैडर मैच पहुंच पा रहे थे $<header>[0]
, $<header>[1]
,, आदि लेकिन उन मैच वस्तुओं रहे हैं तो हम सिर्फ जल्दी से उन्हें stringify। make
आदेश अन्य टोकन इस विशेष डेटा है कि हम बना लिया है का उपयोग करने की अनुमति देता है।
हमारी मूल्य पंक्ति पहचान में दिखेगी, क्योंकि $<value>
टोकन वही हैं जिनकी हम परवाह करते हैं।
method valueRow ($/) {
my @values = $<value>.map: *.Str
make @values;
}
जब हम अंतिम विधि प्राप्त करते हैं, तो हम हैश के साथ सरणी बनाना चाहेंगे।
method TOP ($/) {
my @entries;
my @headers = $<headerRow>.made;
my @rows = $<valueRow>.map: *.made;
for @rows -> @values {
my %entry = flat @headers Z @values;
@entries.push: %entry;
}
make @entries;
}
यहां आप देख सकते हैं कि हम अपने द्वारा संसाधित किए गए सामान का उपयोग कैसे करते हैं : headerRow()
और valueRow()
आप .made
विधि का उपयोग करते हैं । क्योंकि कई made
मान हैं, उनके प्रत्येक मान को प्राप्त करने के लिए , हमें एक नक्शा करने की आवश्यकता है (यह एक ऐसी स्थिति है, जहां मैं व्याकरण में बस लिखने के लिए अपना व्याकरण लिखना चाहता हूं <header><data>
, और डेटा को कई पंक्तियों के रूप में परिभाषित करता हूं, लेकिन यह है) बहुत आसान है) यह बहुत बुरा नहीं है।
अब जबकि हमारे पास दो सरणियों में हेडर और पंक्तियाँ हैं, यह केवल उन्हें हैश की एक सरणी बनाने की बात है, जिसे हम for
लूप में करते हैं । flat @x Z @y
बस तत्वों intercolates, और हैश काम हम क्या मतलब है, लेकिन वहाँ अन्य तरीकों से हैश में सरणी आप चाहते हैं पाने के लिए कर रहे हैं।
एक बार जब आप कर लेते हैं, तो आप make
इसे कर लेते हैं , और फिर यह made
पार्स में उपलब्ध होगा :
say Parser.parse($dat, :actions(ParserActions)).made
-> [{Email => test@email.com, ID => 1, Name => test} {Email => stan@nowhere.net, ID => 321, Name => stan} {}]
इनको एक विधि में लपेटना काफी आम है, जैसे
sub parse-tsv($tsv) {
return Parser.parse($tsv, :actions(ParserActions)).made
}
इस तरह आप सिर्फ कह सकते हैं
my @entries = parse-tsv($dat);
say @entries[0]<Name>; # test
say @entries[1]<Email>; # stan@nowhere.net
Nil
। यह बहुत बंजर है जहाँ तक प्रतिक्रिया जाती है, है ना? डिबगिंग के लिए, यदि आप पहले से ही नहीं हैं, तो कमोड को डाउनलोड करें और / या देखें कि व्याकरण में त्रुटि की रिपोर्ट में कैसे सुधार किया जा सकता है? । आपNil
cuz को अपना पैटर्न बैकट्रैकिंग शब्दार्थ मानते हैं। उस बारे में मेरा जवाब देखें। मैं आपको सलाह देता हूं कि आप पीछे हट जाएं। उस बारे में @ user0721090601 का जवाब देखें। सरासर व्यावहारिकता और गति के लिए, जेजे का उत्तर देखें। इसके अलावा, परिचयात्मक सामान्य जवाब "मैं राकू के साथ एक्स को पार्स करना चाहता हूं। क्या कोई मदद कर सकता है?" ।