C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++のHTMLエンティティパーサー


文字列があるとします。 HTML構文の特殊文字を通常の文字に置き換える1つのHTMLパーサーを設計する必要があります。 HTMLエンティティパーサーは、HTMLコードを入力として受け取り、特殊文字のすべてのエンティティを文字自体に置き換えるパーサーです。これらは、HTMLの特殊文字とそのエンティティです-

  • 引用符-エンティティは「」で、記号文字は「」です。

  • 一重引用符-エンティティは'、記号文字は'です。

  • アンパサンド-エンティティは&であり、記号文字は&です。

  • 大なり記号-エンティティは>であり、記号文字は>です。

  • 符号未満-エンティティは<であり、記号文字は<。

  • スラッシュ-エンティティは⁄で、記号文字は/です。

したがって、入力が「&は変更されたが&ambassador;は変更されていない」のような場合、出力は「&は変更されたが&ambassador;は変更されなかった」になります。

これを解決するには、次の手順に従います-

  • 配列を定義するv=スペースを使用して文字列を分割することによりvを初期化する

  • ret:=空の文字列

  • 1つのマップmを定義します。これにより、すべてのHTMLシンボルがキーとして保持され、対応する特殊文字が値として保持されます

  • 初期化i:=0の場合、i

    • s:=v [i]

    • temp:=空の文字列

    • n:=v [i]

      のサイズ
    • k:=0

    • k

      • v [i、k]が'&'と同じ場合、-

        • temp:=temp + v [i、k]

        • (kを1増やします)

        • (k

          • temp:=temp + v [i、k]

          • (kを1増やします)

        • temp:=temp + v [i、k]

        • (kを1増やします)

        • tempがmのメンバーである場合、-

          • ret:=ret + m [temp]

        • それ以外の場合

          • ret:=ret + temp

        • temp:=空の文字列

      • それ以外の場合

        • ret:=ret + v [i、k]

        • (kを1増やします)

    • tempのサイズが0でなく、tempがmのメンバーである場合、-

      • ret:=ret concatenate m [temp]

    • それ以外の場合、温度のサイズの場合、-

      • ret:=ret concatenate temp

    • iがvのサイズと等しくない場合、-

      • ret:=ret連結空白スペース

  • retを返す

理解を深めるために、次の実装を見てみましょう-

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   vector <string> split(string& s, char delimiter){
      vector <string> tokens;
      string token;
      istringstream tokenStream(s);
      while(getline(tokenStream, token, delimiter)){
         tokens.push_back(token);
      }
      return tokens;
   }
   void out(vector <string> v){
      for(string s : v) cout << s << endl;
   }
   string entityParser(string text) {
      vector<string> v = split(text, ' ');
      string ret = "";
      map<string, string> m;
      m["""] = "\"";
      m["'"] = "\'";
      m["&"] = "&";
      m[">"] = ">";
      m["<"] = "<";
      m["⁄"] = "/";
      for (int i = 0; i < v.size(); i++) {
         string s = v[i];
         string temp = "";
         int n = v[i].size();
         int k = 0;
         while (k < n) {
            if (v[i][k] == '&') {
               temp += v[i][k];
               k++;
               while (k < n && v[i][k] != ';') {
                  temp += v[i][k];
                  k++;
               }
               temp += v[i][k];
               k++;
               if (m.count(temp))
                  ret += m[temp];
               else
                  ret += temp;
               temp = "";
            }
            else {
               ret += v[i][k];
               k++;
            }
         }
         if (temp.size() && m.count(temp)) {
            ret += m[temp];
         }
         else if (temp.size())
            ret += temp;
         if (i != v.size() - 1)
            ret += " ";
      }
      return ret;
   }
};
main(){
   Solution ob;
   cout << (ob.entityParser("& is changed but &ambassador; is not."));
}

入力

"& is changed but &ambassador; is not."

出力

& is changed but &ambassador; is not.

  1. C++での文字列のトークン化

    このセクションでは、C++で文字列をトークン化する方法を説明します。 Cでは、文字配列にstrtok()関数を使用できます。ここに文字列クラスがあります。次に、その文字列から区切り文字を使用して文字列を切り取る方法を説明します。 C ++機能を使用するには、文字列を文字列ストリームに変換する必要があります。次に、getline()関数を使用して、タスクを実行できます。 getline()関数は、文字列ストリーム、出力を送信するための別の文字列、およびストリームのスキャンを停止するための区切り文字を受け取ります。 関数がどのように機能しているかを理解するために、次の例を見てみましょう。 サン

  2. C ++で文字列をトークン化しますか?

    最初の方法は、文字列ストリームを使用して、スペースで区切られた単語を読み取ることです。これは少し制限されていますが、適切なチェックを提供すれば、タスクはかなりうまくいきます。 例 #include <vector> #include <string> #include <sstream> using namespace std; int main() {    string str("Hello from the dark side");    string tmp; // A string