簡體   English   中英

從字符串中提取特定事物

[英]Extracting a specific thing from a string

我有一個格式為<a,b>的字符串,它表示有向圖中的一條邊( a是源, b是目標)。 ab本身也是字符串(例如, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM