• 昨天写的正则表达式


    实习时昨天写了一整天正则表达式,要匹配多个型号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);
    
        }
    
    }
  • 相关阅读:
    快速幂 --- CSU 1556: Jerry's trouble
    iOS masonry 不规则tagView布局 并自适应高度
    iOS 渐变色实现,渐变色圆环,圆环进度条
    iOS scrollView中嵌套多个tableView处理方案
    iOS 多网络请求同步并发
    iOS UIView添加阴影
    什么是比特币,什么是区块链,什么是挖矿,为什么要挖?关于比特币,关于区块链,你想要知道的
    Xcode wifi连接真机调试
    iOS 添加WKWebView导致控制器无法释放的问题
    解决百度网盘非会员下载速度限制的完整方案
  • 原文地址:https://www.cnblogs.com/nomorewzx/p/4654014.html
Copyright © 2020-2023  润新知