मेरे पास प्रारूप में एक पाठ फ़ाइल है:
number tab word tab word tab junk
number tab word tab word tab junk
number tab word tab word tab junk
number tab word tab word tab junk
number tab word tab word tab junk
प्रत्येक पंक्ति के लिए मैं संख्या को एक में रखना चाहता हूंuint32_t, फिर दो शब्दों को तार में और फिर बाकी पंक्ति को अनदेखा करें। मैं फ़ाइल को मेमोरी में लोड करके और फिर एक बार में बाइट के माध्यम से काम कर सकता था, लेकिन मुझे विश्वास है कि एक सुंदर रेग्क्स मेरे लिए यह कर सकता है। कोई विचार?
मैं X ++ में #include का उपयोग करके C ++ में काम कर रहा हूं - यह एक कमांडलाइन टूल है, इसलिए कोई वास्तविक आउटपुट नहीं है, मैं सिर्फ डेटा को अन्य डेटा के साथ तुलना करने के लिए स्टोर कर रहा हूं।
उत्तर:
उत्तर № 1 के लिए 1extern bool DoStuff(unsigned n,
const std::string &s0,
const std::string &s1);
bool ProcessFile(const std::string &sFileName)
{
std::ifstream ifs(sFileName);
if (!ifs)
return false;
while (ifs)
{
unsigned n;
std::string s0, s1;
ifs >> n >> s0 >> s1;
if (ifs.bad() || !DoStuff(n, s0, s1))
return false;
ifs.ignore(std::numeric_limits<int>::max(), "n");
}
return !ifs.bad();
}
उत्तर № 2 के लिए 1
मैट, आप इस सरल regex का उपयोग कर सकते हैं:
(?im)^(d+)t([a-z]+)t([a-z]+)
यह समूह 1 में संख्या, समूह 2 में पहला शब्द और समूह 3 में दूसरा शब्द कैप्चर करता है।
उन्हें समूह 1, 2 और 3 से निकालने के लिए, मैं नहींअपने सटीक C ++ सिंटैक्स के बारे में सुनिश्चित करें, लेकिन यह कोड स्टब मैचों और समूहों पर पुनरावृति करने का एक विचार देता है। ध्यान दें कि इस मामले में हम समग्र मैचों के बारे में परवाह नहीं करते हैं, बस कैप्चरिंग समूह।
try {
TRegEx RegEx("(?im)^(\d+)t([a-z]+)t([a-z]+)", TRegExOptions() << roIgnoreCase << roMultiLine);
TMatch Match = RegEx.Match(SubjectString);
while (Match.Success) {
for (int i = 1; i < Match.Groups.Count; i++) {
TGroup Group = Match.Groups[i];
if (Group.Success) {
// matched text: Group.Value
// match start: Group.Index
// match length: Group.Length
}
}
Match = Match.NextMatch();
}
} catch (ERegularExpressionError *ex) {
// Syntax error in the regular expression
}