猿问

用于验证文件的正则表达式或函数?

我手头有一项任务是验证包含以下数据的文本文件的架构


以下格式的 50 个条目,


序列号是从 1-50 后跟一个制表符,然后是一个随机数 n,范围从 100<=n<=500


e.g. 1 <tab> 256

由于正则表达式更容易检查文件的模式并且更易于维护我更喜欢使用正则表达式而不是一个将解析每个字符串并立即验证的类


输出文件应该是这样的


Line 1 formatted correctly

Invalid format on line 2 (51 1000) + (Error message that can be set using a custom exception class)

我的问题是,正则表达式能否强大到足以给我所需的输出,即引发异常以正确的方式设置?


我的尝试如下


public class TestOutput {


    private final int MAX_LINES_TO_READ = 50;


    private final String REGEX = "RAWREGEX";


    public void testFile(String fileName) {


        int lineCounter = 1;


        try {


            BufferedReader br = new BufferedReader(new FileReader(fileName));


            String line = br.readLine();


            while ((line != null) && (lineCounter <= MAX_LINES_TO_READ)) {


                // Validate the line is formatted correctly based on regular expressions                

                if (line.matches(REGEX)) {

                    System.out.println("Line " + lineCounter + " formatted correctly");

                }

                else {

                    System.out.println("Invalid format on line " + lineCounter + " (" + line + ")");

                }


                line = br.readLine();

                lineCounter++;

            }


            br.close();


        } catch (Exception ex) {

            System.out.println("Exception occurred: " + ex.toString());

        }

    }


    public static void main(String args[]) {


        TestOutput vtf = new TestOutput();


        vtf.testFile("transactions.txt");

    }   

}

这是我的问题

  1. 最佳设计应该是什么样子(是否使用正则表达式)?

  2. 如果是,使用什么正则表达式?


呼啦一阵风
浏览 118回答 3
3回答

开满天机

使用此正则表达式:String REGEX = "([1-9]|[1-4]\\d|50)\t([1-4]\\d\\d|500)";解释...[1-9]|[1-4]\\d|50表示“任何数字 1-50”,通过三个交替 1-9、10-49 和 50 实现。同样,[1-4]\\d\\d|500表示“100-500”,通过两次交替 100-499 和 500 实现。只有 50 行,“性能”是无关紧要的(除非你每秒执行 100 次)——选择最易读和理解的方法。如果您可以使用正则表达式,它通常会产生更少的代码,并且性能足够好。测试代码:private final String REGEX = "([1-9]|[1-4]\\d|50)\\t([1-4]\\d\\d|500)";public void testFile(String fileName) {    int lineCounter = 1;    try {        BufferedReader br = new BufferedReader(new FileReader(fileName));        String line = br.readLine();        while ((line != null) && (lineCounter <= MAX_LINES_TO_READ)) {            if (line.matches(REGEX)) {                System.out.println("Line " + lineCounter + " formatted correctly");            } else {                System.out.println("Invalid format on line " + lineCounter + " (" + line + ")");            }            line = br.readLine();            lineCounter++;        }        br.close();    } catch (Exception ex) {        System.out.println("Exception occurred: " + ex.toString());    }}测试文件:1   12350  34623  14568  4551   535输出:Line 1 formatted correctlyLine 2 formatted correctlyLine 3 formatted correctlyInvalid format on line 4 (68    455)Invalid format on line 5 (1 535)

牧羊人nacy

这是一个使用正则表达式的实现。匹配器为每个匹配项提供子表达式。并且这些限制是用 Java 实现的。boolean matchLine(String line) {&nbsp; &nbsp; Pattern p = Pattern.compile("^(\\d+)\\t(\\d+)");&nbsp; &nbsp; boolean ok = false;&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; Matcher m = p.matcher(line);&nbsp; &nbsp; &nbsp; &nbsp; int i = Integer.parseInt(m.group(1));&nbsp; &nbsp; &nbsp; &nbsp; int n = Integer.parseInt(m.group(2));&nbsp; &nbsp; &nbsp; &nbsp; ok = 1 <= i && i <= MAX_LINES_TO_READ && 100<=n && n<=500;&nbsp; &nbsp; } catch(NumberFormatException e){};&nbsp; &nbsp; return ok;}

开心每一天1111

下面只是一个快速的实现。请注意,对于这样一个微不足道的问题,速度不是问题。如评论中所述,为数字范围编写正则表达式可能比仅拆分选项卡上的每一行、从字符串部分解析整数并使用 good old 检查正确的范围更难if。public class SplitByTab {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; String input = "1&nbsp; &nbsp;123\n" + "2 456\n" + "3 789\n" + "4 234\n" + "5 345\n" + "6 890";&nbsp; &nbsp; &nbsp; &nbsp; for (String line : input.split("\\r?\\n")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validateLine(line);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private static void validateLine(String line) {&nbsp; &nbsp; &nbsp; &nbsp; String[] parts = line.split("\\t");&nbsp; &nbsp; &nbsp; &nbsp; if (parts.length != 2) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException(String.format("line '%s' does not contain exactly one tab", line));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Integer serial = Integer.valueOf(parts[0]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (serial < 0 || serial > 50) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String.format("the value of the serial %d is not between 0 and 50", serial));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } catch (NumberFormatException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String.format("the firt part '%s' of line '%s' is not an integer", parts[0], line));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Integer randomNumber = Integer.valueOf(parts[1]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (randomNumber < 0 || randomNumber > 500) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String.format("the value of the random number %d is not between 0 and 500", randomNumber));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } catch (NumberFormatException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String.format("the firt part '%s' of line '%s' is not an integer", parts[0], line));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}输出:Exception in thread "main" java.lang.IllegalArgumentException: the value of the random number 789 is not between 0 and 500
随时随地看视频慕课网APP

相关分类

Java
我要回答