我在日志文件中有这样的行:
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?
是一个很好的选择,如何计算哪个是最后一个点?
答案 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; } `