[英]Extracting a specific thing from a string
我有一個格式為<a,b>
的字符串,它表示有向圖中的一條邊( a
是源, b
是目標)。 a
和b
本身也是字符串(例如, a
可以是"Square"
而b
是"Circle"
)。
我需要構建一個提取a
的 function 和另一個提取b
的 function 。 所以簽名將是:
string getSource(String edge); //will return b
string getTarget(String edge); //will return a
我正在使用std::string
庫來表示這些字符串。
我知道我需要找到一種方法來找到','
將它們分隔在字符串中間,並擺脫'<'
和'>'
。 但是我在std::string
中找不到 function 可以幫助我做到這一點。
你會怎么做?
這似乎是正則表達式的一個很好的用例:
std::regex sd {R"(<(.*),(.*)>)"};
然后你的函數可以寫成:
std::string getSource(std::string const & edge) {
std::smatch m;
std::regex_match(edge, m, sd);
return m[1].str();
}
在getTarget
你會返回m[2].str();
.
如果您確定字符串格式正確,只需使用std::find
定位感興趣的字符,然后從這些迭代器構造一個新字符串即可。 例如:
std::string getSource(std::string const & edge) {
return {
std::next(std::find(std::begin(edge), std::end(edge), '<')),
std::find(std::begin(edge), std::end(edge), ',')
};
}
std::string getTarget(std::string const & edge) {
return {
std::next(std::find(std::begin(edge), std::end(edge), ',')),
std::find(std::begin(edge), std::end(edge), '>')
};
}
如果字符串的格式不正確,那么這些函數可能會表現出未定義的行為。 這可以通過使用幫助程序 function 輕松解決:
template <typename T>
std::string checkedRangeToString(T begin, T end) {
if (begin >= end) {
// Bad format... throw an exception or return an empty string?
return "";
}
return {begin, end};
}
std::string getSource(std::string const & edge) {
return checkedRangeToString(
std::next(std::find(std::begin(edge), std::end(edge), '<')),
std::find(std::begin(edge), std::end(edge), ',')
);
}
std::string getTarget(std::string const & edge) {
return checkedRangeToString(
std::next(std::find(std::begin(edge), std::end(edge), ',')),
std::find(std::begin(edge), std::end(edge), '>')
);
}
這聽起來像是屬於 class 的構造函數,它采用std::string
參數並對其進行解析。
class edge {
public:
edge(const std::string& str);
std::string source() const { return src; }
std::string target() const { return tgt; }
private:
std::string src;
std::string tgt;
};
edge::edge(const std::string& str) {
auto comma = std::find(std::begin(str), std::end(str), ',');
if (str.length() < 3 || comma == std::end(str) || str.front() != '<' || str.back() != '>')
throw std::runtime_error("bad input");
src = std::string(std::next(std::begin(str)), comma);
tgt = std::string(std::next(comma), std::prev(std::end(str)));
}
對於如此簡單的解析,我不會使用正則表達式。 正則表達式很昂貴並且被高估了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.