【问题标题】:Extract text from large file using RegEx?使用正则表达式从大文件中提取文本?
【发布时间】:2015-06-07 06:35:58
【问题描述】:

我有一个大文件,里面有一堆数据,但基本上我想做的是只抓取其中的一部分,让我解释一下我感兴趣的部分:

(将“x”想象为 IP 地址)

(将“?”想象为任何字母数字字符/w 任何长度)

(将“MD5”想象成一个 MD5 哈希)

(实际 - 不是字面意思 - 下面的文本文件)


'xxx.xxx.xxx.xxx'

xxxxxxxxxx

“?”

“?”

'MD5'

现在我的查询是以下一个,我如何识别线路

'xxx.xxx.xxx.xxx'

在一个文件的开头任何地方,然后自动写入另一个文件中的'?'条目和找到的每个 IP 地址实例的“MD5”条目。

所以简而言之,程序应该从文件的开头开始,读取内容,如果它到达一个 IP 地址(Regex: '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' 对我来说很好),跳过下面的一行,然后开始复制其他数据到另一个文件,直到它到达 MD5 条目(Regex: '[a-f0-9]{32}' 对我来说很好),然后从那个点再次迭代,等等寻找另一个 IP 地址实例等等。它应该保持这样做直到到达文件的末尾。

我正在尝试自己做,但我什至不知道从哪里开始,也不知道做这件事的方法。

【问题讨论】:

  • x第二行没有点的那一行是什么?
  • @Tomalak,一些身份证号码,不是相对重要的。
  • 我不会使用正则表达式来读取文件。在以下网页上使用类似于我的代码的代码:stackoverflow.com/questions/30457660/…。您可以使用正则表达式来识别一行是否包含 IP,但不要在整个文件上使用正则表达式。请发布文件的实际部分,以便我提供帮助。从事文本解析已有 40 多年。

标签: c# regex text


【解决方案1】:

您可以使用以下内容来匹配您要查找的内容..并将其复制到所需的位置/文件:

('\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b')(\s*.+\s*)([\s\S]*?)('\b[a-f0-9]{32}\b')

并提取$1$3$4

DEMO

代码:

String regex = "('\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b')(\\s*.+\\s*)([\\s\\S]*?)('\\b[a-f0-9]{32}\\b')";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(myString);
while (m.find()) {
    System.out.println("end(): " + m.group(1));
    //System.out.println("end(): " + m.group(2));
    System.out.println("end(): " + m.group(3));
    System.out.println("end(): " + m.group(4));
}

【讨论】:

  • 您的正则表达式在我这边产生“0 个匹配项”。
  • @manchala regex101.com/r/eZ6lU9/1 - 这是实际文本文件的一部分。你也可以像我一样评估你的正则表达式。
  • @AxDSanMuramasa regex101 不支持 c#.. 我正在使用 regexstorm 进行测试.. 检查答案中的演示..
  • 我现在看到了,您现在可以检查一下这个REGEX Real World Application Simulation,因为您注意到它现在有点接近了,但是 IP 地址识别需要一些工作,实际上我想跳过下面的行IP地址,并识别2个用户+MD5
  • @AxDSanMuramasa 你能用预期的输出更新这个问题吗?
【解决方案2】:

鉴于您的文件是机器生成的并且整体模式非常具体,我认为没有必要对 IP 地址过于具体。

在模式的其余部分 (*) 的上下文中,将其匹配为“单引号中的一堆数字和点”可能就足够了。

这是一个符合您对named groups 的整个要求的表达式:

^'(?<IP>[\d.]+)'\s+
^(?<ID>\w*)\s+
^'(?<line1>\w*)'\s+
^'(?<line2>\w*)'\s+
^'(?<MD5>[A-Fa-f0-9]{32})'

将它与MultilineIgnorePatternWhitespace regex options 一起使用(后者意味着您可以保留正则表达式布局以获得更好的可读性)。


(*) 此外,IP 地址的正则表达式模式无处不在,举不胜举。当然,如果您认为有必要,您可以使用比 '[\d.]+' 更复杂的东西。

【讨论】:

  • 这是一种更方便的方法,但是我如何遍历找到的每个元素...?我应该使用 for 循环并识别它们吗?
  • 是的,.NET 正则表达式文档以及互联网上的许多答案和代码示例向您展示了这是如何完成的。这是一个非常基本的问题,您可以自己轻松解决。我回答的重点是更多地强调一些有用的功能。 NET 正则表达式。
【解决方案3】:

我已经在 J​​ava 中进行了如下尝试。

公共类 TestRegex {

/**
 * @param args
 */
public static void main(String[] args)
{
    String input = "assasasa 123.234.223.223 333 aad sddsf 343sdd sds23343 ssdfs33344 MD5=aas jjsjjdjd 143.234.223.223 333 aad sddsf 343sdd sds23343 ssdfs33344 MD5=asas";
    String regexPattern = "(\\b[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\b).*?([A-Z a-z]+[0-9]+=.*?\\s)";
    Matcher m = null;
    Pattern pattern = Pattern.compile(regexPattern);
    m = pattern.matcher(input);
    // System.out.println(matcher.toString());
    while (m.find()) {
        System.out.println("start(): " + m.start());
        System.out.println("end(): " + m.end());
        System.out.println("end(): " + m.toString());
        System.out.println("end(): " + m.group(1));
        System.out.println("end(): " + m.group(2));
    }

}

}

【讨论】:

    猜你喜欢
    • 2020-01-29
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2021-12-12
    相关资源
    最近更新 更多