सी ++ 11 रेगेक्स और वैरिएडिक टेम्पलेट्स के साथ पायथन-जैसी प्रारूप स्ट्रिंग फ़ंक्शन कार्यान्वयन।
/**
Helper code to unpack variadic arguments
*/
namespace internal
{
template<typename T>
void unpack(std::vector<std::string> &vbuf, T t)
{
std::stringstream buf;
buf << t;
vbuf.push_back(buf.str());
}
template<typename T, typename ...Args>
void unpack(std::vector<std::string> &vbuf, T t, Args &&... args)
{
std::stringstream buf;
buf << t;
vbuf.push_back(buf.str());
unpack(vbuf, std::forward<Args>(args)...);
}
}
/**
Python-like string formatting
*/
template<typename ... Args>
std::string format(const std::string& fmt, Args ... args)
{
std::vector<std::string> vbuf; // store arguments as strings
std::string in(fmt), out; // unformatted and formatted strings
std::regex re_arg("\\{\\b\\d+\\b\\}"); // search for {0}, {1}, ...
std::regex re_idx("\\b\\d+\\b"); // search for 0, 1, ...
std::smatch m_arg, m_idx; // store matches
size_t idx = 0; // index of argument inside {...}
// Unpack arguments and store them in vbuf
internal::unpack(vbuf, std::forward<Args>(args)...);
// Replace all {x} with vbuf[x]
while (std::regex_search(in, m_arg, re_arg)) {
out += m_arg.prefix();
if (std::regex_search(m_arg[0].str(), m_idx, re_idx)) {
idx = std::stoi(m_idx[0].str());
}
if(idx < vbuf.size()) {
out += std::regex_replace(m_arg[0].str(), re_arg, vbuf[idx]);
}
in = m_arg.suffix();
}
out += in;
return out;
}
उदाहरण: cpp.sh/6nli
क्या अच्छे पुराने सी/कश्मीर एंड आर xxprintf साथ कुछ गड़बड़ है()? – FoggyDay
मुझे इसे सामान्य रूप से पसंद है लेकिन यह सीधे 'स्ट्रिंग' स्वीकार नहीं कर सकता है, जो परेशान है। मैं एक ऐसी विधि पसंद करूंगा जिसके लिए मुझे अपने सभी तारों पर '.c_str()' कॉल करने की आवश्यकता नहीं है। इसके अलावा, यह कहीं भी पाइथन के 'प्रारूप() 'के रूप में अच्छा नहीं है। –
@FoggyDay: कोई प्रकार की सुरक्षा नहीं। बिलकुल। शून्य विस्तारशीलता। –