提取两个单词之间的域名

时间:2012-07-19 21:36:37

标签: c++ regex linux unix gcc

我在日志文件中有这样的行:

11-test.domain1.com已记录...

37-user1.users.domain2.org已记录...

48-me.server.domain3.net已记录...

如何在没有子域的情况下提取每个域?介于" - "之间的东西和"记录"

我在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);

谢谢!

P.S。不,我不能使用perl,因为这部分是在一个由其他人制作的更大的c程序中。

编辑:

我用这个替换代码:

   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?

是一个很好的选择,如何计算哪个是最后一个点?

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:0)

是否采用标准格式? 看起来是这样,有分裂功能吗?

修改 这是一些逻辑。 遍历每个要解析的域 找到一个函数来定位第一个字符串“ - ”的索引    接下来找到第二个字符串的索引减去第一个字符串“Logged” 现在您拥有完整的域名。

一旦你有完整的域“拆分”域到你选择的对象(我使用了一个数组) 现在您已将数组拆开,找到要重组的值的索引(连接)以仅捕获域。

注意用C#编写

定义第一个值和第二个值的主要方法

`static void Main(string[] args)
        {
            string firstValue ="-";
            string secondValue = "Logged";
            List domains = new List { "11-test.domain1.com Logged", "37-user1.users.domain2.org Logged","48-me.server.domain3.net Logged"};
            foreach (string dns in domains)
            {
                Debug.WriteLine(Utility.GetStringBetweenFirstAndSecond(dns, firstValue, secondValue));
            }
        }
`

解析字符串的方法:

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

            if(string.IsNullOrEmpty(str))
            {
                //throw an exception, return gracefully, whatever you determine
            }
            else
            {
                //This can all be done in one line, but I broke it apart so it can be better understood.
                //returns the first occurrance.
                //int start = str.IndexOf(firstStringToFind) + 1;

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

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

                //i.e. Definitely not quite as legible, but doesn't create object unnecessarily
                domain = 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]);
                    }
                }
            }

            return domain;
        }
`