1

ログファイルに次のような行があります。

11-test.domain1.com がログに記録されました ...

37-user1.users.domain2.org ログに記録されました ...

48-me.server.domain3.net ログに記録されました...

サブドメインなしで各ドメインを抽出するにはどうすればよいですか? "-" と "Logged" の間の何か

C++ (Linux) で次のコードを使用していますが、うまく抽出できません。もちろん、いくつかの例があれば、抽出された文字列を返す関数は素晴らしいでしょう。

       regex_t    preg;
       regmatch_t mtch[1];
       size_t     rm, nmatch;
       char tempstr[1024] = "";
       int start;
       rm=regcomp(&preg, "-[^<]+Logged", REG_EXTENDED);
       nmatch = 1;
       while(regexec(&preg, buffer+start, nmatch, mtch, 0)==0) /* Found a match */
               {
                 strncpy(host, buffer+start+mtch[0].rm_so+3, mtch[0].rm_eo-mtch[0].rm_so-7);
                 printf("%s\n", tempstr);
                 start +=mtch[0].rm_eo;
                 memset(host, '\0', strlen(host));
               }
       regfree(&preg);

ありがとうございました!

PS いいえ、この部分は他の人が作成したより大きな C プログラムの中にあるため、これに perl を使用することはできません。

編集:

コードを次のコードに置き換えます。

   const char *p1 = strstr(buffer, "-")+1;
   const char *p2 = strstr(p1, " Logged");
   size_t len = p2-p1;
   char *res = (char*)malloc(sizeof(char)*(len+1));
   strncpy(res, p1, len);
   res[len] = '\0';

サブドメインを含むドメイン全体を非常にうまく抽出しています。abc.def.domain.com から domain.com または domain.net だけを抽出するにはどうすればよいですか?

strtok は良いオプションですか、最後のドットを計算するにはどうすればよいですか?

4

2 に答える 2

1
#include <vector>
#include <string>
#include <boost/regex.hpp>

int main()
{
    boost::regex re(".+-(?<domain>.+)\\s*Logged");
    std::string examples[] = 
    {
        "11-test.domain1.com Logged ...",
        "37-user1.users.domain2.org Logged ..."
    };
    std::vector<std::string> vec(examples, examples + sizeof(examples) / sizeof(*examples));
    std::for_each(vec.begin(), vec.end(), [&re](const std::string& s)
    {
        boost::smatch match;
        if (boost::regex_search(s, match, re))
        {
            std::cout << match["domain"] << std::endl;
        }
    });
}

http://liveworkspace.org/code/1983494e6e9e884b7e539690ebf98eb5 boost::regex でこのようなもの。pcreについてはわかりません。

于 2012-07-19T21:50:51.443 に答える
0

は標準形式ですか?そのように見えますが、分割機能はありますか?

編集: ここにいくつかのロジックがあります。解析する各ドメインを反復処理します。最初の文字列「-」のインデックスを見つける関数を見つけます。次に、2番目の文字列から最初の文字列「Logged」を引いたインデックスを見つけます。これで完全なドメインができました。

完全なドメインを取得したら、ドメインを選択したオブジェクトに「分割」します(配列を使用しました)。配列を分解したので、再構築(連結)する値のインデックスを見つけて、ドメインのみをキャプチャします。

C#で記述

最初の値と2番目の値を定義するメインメソッド

`static void Main(string [] args)
        {{
            string firstValue = "-";
            string secondValue="ログに記録されました";
            List domain = new List {"11-test.domain1.com Logged"、 "37-user1.users.domain2.org Logged"、 "48-me.server.domain3.net Logged"};
            foreach(ドメイン内の文字列DNS)
            {{
                Debug.WriteLine(Utility.GetStringBetweenFirstAndSecond(dns、firstValue、secondValue));
            }
        }
`

文字列を解析するメソッド:

`public string GetStringBetweenFirstAndSecond(string str、string firstStringToFind、string secondStringToFind)
        {{
            string domain = string.Empty;

            if(string.IsNullOrEmpty(str))
            {{
                //例外をスローし、決定したものは何でも正常に返します
            }
            そうしないと
            {{
                //これはすべて1行で実行できますが、理解しやすいように分割しました。
                //最初のオカレンスを返します。
                // int start = str.IndexOf(firstStringToFind)+ 1;

                // int end = str.IndexOf(secondStringToFind);

                // domain = str.Substring(start、end --start);

                //つまり、はっきりと読みやすくはありませんが、不必要にオブジェクトを作成することはありません
                ドメイン=str.Substring((str.IndexOf(firstStringToFind)+ 1)、str.IndexOf(secondStringToFind)-(str.IndexOf(firstStringToFind)+ 1));

                string [] dArray = domain.Split('。');

                if(dArray.Length> 0)
                {{
                    if(dArray.Length> 2)
                    {{
                        domain = string.Format( "{0}。{1}"、dArray [dArray.Length-2]、dArray [dArray.Length-1]);
                    }
                }
            }

            ドメインを返す;
        }
`
于 2012-07-19T21:43:04.437 に答える