我想从日志文件中提取某些URL。但我只想提取那些排名 1。或 2 的查询。日志文件包含colum itemRank ,给出排名。 到目前为止,我能够通过扫描文本来提取某些URL。但我不知道如何实现只点击第一个或第二个URL的条件。
例如,这就是日志文件的一部分:
(列是ID,日期,时间,RANK,网址)
763570 2006-03-06 14:09:48 2 http://something.com
763570 2006-03-06 14:09:48 3 http://something.com
这里我只想提取第一个查询,因为它排名为2.
到目前为止,这是我的代码:
public class Scanner {
public static void main(String[] args) throws FileNotFoundException {
File testFile = new File ("C:/Users/Zyaad/logs.txt");
Scanner s = new Scanner(testFile);
int count=0;
String pattern="http://ontology.buffalo.edu";
while(s.hasNextLine()){
String line = s.nextLine();
if (line.contains(pattern)){
count++;
System.out.println(count + ".query: " );
System.out.println(line);
}
} System.out.println("url was clicked: "+ count + " times");
s.close();
}
}
如何打印1.查询?我尝试了像[\t\n\b\r\f] [1,2]{1}[\t\n\b\r\f]
这样的正则表达式,但这不起作用。
答案 0 :(得分:1)
一种简单(可能过于简单)的方法是:
示例强>
// assume this is the file you're parsing so I don't have to repeat
// the whole Scanner part here
String theFile = "763570 2006-03-06 14:09:48 2 http://something2.com\r\n" +
"763570 2006-03-06 14:09:48 3 http://something3.com";
// | your starting digit of choice
// | | one white space
// | | | group 1 start
// | | | | partial protocol of the URL
// | | | | | any character following in 1+ instances
// | | | | | | end of group 1
// | | | | | |
Pattern p = Pattern.compile("2\\s(http.+)");
Matcher m = p.matcher(theFile);
while (m.find()) {
// back-referencing group 1
System.out.println(m.group(1));
}
<强>输出强>
http://something2.com
注意强>
通常建议使用正则表达式解析日志文件。
你可能最好长期实现你自己的解析器并将标记逐项列为对象的属性(我假设每行1个),然后根据需要操作它们。
答案 1 :(得分:0)
您可以根据日期和时间创建正则表达式时间模式,或者您也可以从时间模式开始。
yyyy-MM-dd hh:mm:ss 1|2
日期&amp;时间模式后跟1或2
\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s[1|2]\s
时间模式后跟1或2
\d{2}:\d{2}:\d{2}\s[1|2]\s
示例代码:
String[] str=new String[] { "763570 2006-03-06 14:09:48 2 http://something.com",
"763570 2006-03-06 14:09:48 3 http://something.com" };
Pattern p = Pattern
.compile("\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}\\s[1|2]\\s");
for (String s : str) {
Matcher m = p.matcher(s);
if (m.find()) {
System.out.println(s.substring(m.end()));
}
}
答案 2 :(得分:0)
你可以在这里找到一些useful patterns。 如果可以使用其他工具,我建议使用logstash,这是一个用于收集和解析日志的令人印象深刻的工具。
答案 3 :(得分:0)
您可以像这样提取排名为1或2的网址:
/(?<=\s(?:1|2)\s).*$/
如果网址前面带有1或2,它将抓取该行的最后一部分。
答案 4 :(得分:0)
试试这个:
public static void main(String[] args) throws FileNotFoundException {
int count = 0;
// create date pattern
// source:https://github.com/elasticsearch/logstash/blob/master/patterns/grok-patterns
String yearPattern = "(?>\\d\\d){1,2}";
String monthNumPattern = "(?:0?[1-9]|1[0-2])";
String monthDayPattern = "(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])";
String hourPattern = "(?:2[0123]|[01]?[0-9])";
String minutePattern = "(?:[0-5][0-9])";
String secondPattern = "(?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?)";
String datePattern = String.format("%s-%s-%s %s:%s:%s", yearPattern,
monthNumPattern, monthDayPattern, hourPattern, minutePattern,
secondPattern);
// create url pattern
// source: http://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149
String urlPattern = "(https?://)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([/\\w \\.-]*)*/?";
Pattern pattern = Pattern.compile("(\\d+) (" + datePattern
+ ") (\\d+) (" + urlPattern + ")");
String data = "763570 2006-03-06 14:09:48 3 http://something.com\n"
+ "763570 2006-03-06 14:09:48 2 http://something.com\n"
+ "763570 2006-03-06 14:09:48 1 http://something.com";
ByteArrayInputStream is = new ByteArrayInputStream(data.getBytes());
java.util.Scanner s = new java.util.Scanner(is);
while (s.hasNextLine()) {
String line = s.nextLine();
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
if (matcher.find(3)) {
int rank = Integer.parseInt(matcher.group(3));
if (rank == 1 || rank == 2) {
count++;
}
}
}
}
System.out.println("url was clicked: " + count + " times");
s.close();
}
这将输出&#34; url被点击:2次&#34;对于包含以下内容的文件: