昨天写的正则表达式

实习时昨天写了一整天正则表达式,要匹配多个型号ONU交换机返回的报文数据,测试数据文本文档大小200MB+,共有200万+条数据,由4家厂商的交换机返回数据。

要写正则就要先看数据格式,200MB+的文本文件,NotePad++根本打不开,Sublime Text2打开后电脑变得很慢,根本不可能在Sublime Text里使用正则匹配,数据翻页都卡。就在网上找到了一段分割文本文件的Java代码,感谢 stackoverflow.com 源网址看这里 ,我把代码贴下来。

分割好后,就粘贴了一部分数据开始写正则,基本的思路是,开始匹配一部分,然后使用Java对整个文档进行测试,然后找到不匹配的数据,迭代匹配。

整个过程还是比较痛苦的,在不断发现新的格式问题。最后不得不使用两个正则表达式作匹配,因为有些厂商在做报文的时候,格式并不统一:

  1. 字段之间的分隔,有些厂商是以Tab空白符分割,有些厂商是以2个或更多Space空白符分割;
  2. 字段内部,有些厂商是以“-”连接字段内的各部分,组成整个字段,有些厂商字段内部使用了单个Space空白符;
  3. 字段个数,大部分厂商是返回的报文有12个字段,但是某商的某部分型号交换机,返回的是……11个字段,同时使用了2个Space空白符分割字段,字段内部使用单个Space空白符。

  像3那样的返回数据很难分辨出到底是含有多少字段,某商……加油。我是在解决了1和2的问题之后,发现还有一些无法匹配的字段,仔细比对数据之后才发现只有11个字段。在解决1和2的过程中,发现由于分割符的区别,不可能只使用 “s” 实现所有数据的字段分隔:

  1. 字段间以Tab分隔的报文格式,则以 “ ” 分隔各个字段,为了匹配字段内部的Space空白符,使用 ` [Ss]*? `规则,这个规则是在两个Tab符之间,使用懒惰原则匹配出任意字符与任意空白符的字符串;
  2. 字段间以2个或更多Space分隔的报文格式,根据Space空白符出现的次数进行分隔,规则是 `s{2,}`,匹配字段内部的Space空白符,思路同1,规则更改为`s{2,}[Ss]*?s{2,}`;
  3. 部分只有11个字段的报文数据,是#2的子集,因此寻找方法修改#2的匹配规则,好在缺失的报文是同一列,举例说明缺失的字段为“A  B  C”中间的B字段,A与C之间在缺失B时,使用了4个Space空白符进行分隔。解决方案:在匹配到A字段后,放弃`s{2,}S+s{2,}`规则,而改为`s{2}[Ss]*?s{1,}`,即A字段后匹配到2个空白符,接着使用懒惰匹配,在2个空白字符与至少1个空白字符之间,匹配任意非空白字符与空白字符组合的字符串。举例说明更好一点:
#1 正常字段数(字段以2空格符分割)
A  B  C
adkc  kdlsk  kslakd

#2 缺少字段B数据(字段以4空格符分割)
A    C
adkc    kslakd

匹配规则
S+s{2}([Ss]*?)s{1,}S+

S+会匹配到字段A,s{2}会匹配到字段A后的2个空格字符,[Ss]*?是懒惰 匹配非空白字符与空白字符混合任意次,直到遇到“最少一个空白符字段”,即s{1,}所表示规则,此时#1会匹配到B字段,#2会匹配到空字符,因为在2个空白符之后,还是跟着空格符。S+匹配到C字段。

Java分割文本文件源代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class TextFileSplit {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.out.println("Invalid Input!");
        }

        //第一个参数是文件路径
        File file = new File(args[0]);

        //第二个参数是每个文件的行数
        int numLinesPerChunk = Integer.parseInt(args[1])/;

        BufferedReader reader = null;
        PrintWriter writer = null;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        String line;        

        long start = System.currentTimeMillis();

        try {
            line = reader.readLine();
            for (int i = 1; line != null; i++) {
                writer = new PrintWriter(new FileWriter(args[0] + "_part" + i + ".txt"));
                for (int j = 0; j < numLinesPerChunk && line != null; j++) {
                    writer.println(line);
                    line = reader.readLine();
                }
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.close();

        long end = System.currentTimeMillis();

        System.out.println("Taken time[sec]:");
        System.out.println((end - start) / 1000);

    }

}
原文地址:https://www.cnblogs.com/nomorewzx/p/4654014.html