为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

呼啦一阵风 2023-04-26 16:44:40
我手头有一项任务是验证包含以下数据的文本文件的架构以下格式的 50 个条目,序列号是从 1-50 后跟一个制表符,然后是一个随机数 n,范围从 100<=n<=500e.g. 1 <tab> 256由于正则表达式更容易检查文件的模式并且更易于维护我更喜欢使用正则表达式而不是一个将解析每个字符串并立即验证的类输出文件应该是这样的Line 1 formatted correctlyInvalid 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");    }   }这是我的问题最佳设计应该是什么样子(是否使用正则表达式)?如果是,使用什么正则表达式?
查看完整描述

3 回答

?
开满天机

TA贡献1786条经验 获得超12个赞

使用此正则表达式:

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   123

50  346

23  145

68  455

1   535

输出:


Line 1 formatted correctly

Line 2 formatted correctly

Line 3 formatted correctly

Invalid format on line 4 (68    455)

Invalid format on line 5 (1 535)


查看完整回答
反对 回复 2023-04-26
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

这是一个使用正则表达式的实现。匹配器为每个匹配项提供子表达式。并且这些限制是用 Java 实现的。


boolean matchLine(String line) {

    Pattern p = Pattern.compile("^(\\d+)\\t(\\d+)");

    boolean ok = false;

    try {

        Matcher m = p.matcher(line);

        int i = Integer.parseInt(m.group(1));

        int n = Integer.parseInt(m.group(2));

        ok = 1 <= i && i <= MAX_LINES_TO_READ && 100<=n && n<=500;

    } catch(NumberFormatException e){};


    return ok;

}


查看完整回答
反对 回复 2023-04-26
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

下面只是一个快速的实现。请注意,对于这样一个微不足道的问题,速度不是问题。如评论中所述,为数字范围编写正则表达式可能比仅拆分选项卡上的每一行、从字符串部分解析整数并使用 good old 检查正确的范围更难if。


public class SplitByTab {


    public static void main(String[] args) {

        String input = "1   123\n" + "2 456\n" + "3 789\n" + "4 234\n" + "5 345\n" + "6 890";


        for (String line : input.split("\\r?\\n")) {

            validateLine(line);

        }

    }


    private static void validateLine(String line) {

        String[] parts = line.split("\\t");

        if (parts.length != 2) {

            throw new IllegalArgumentException(String.format("line '%s' does not contain exactly one tab", line));

        }

        try {

            Integer serial = Integer.valueOf(parts[0]);

            if (serial < 0 || serial > 50) {

                throw new IllegalArgumentException(

                        String.format("the value of the serial %d is not between 0 and 50", serial));

            }

        } catch (NumberFormatException e) {

            throw new IllegalArgumentException(

                    String.format("the firt part '%s' of line '%s' is not an integer", parts[0], line));

        }

        try {

            Integer randomNumber = Integer.valueOf(parts[1]);

            if (randomNumber < 0 || randomNumber > 500) {

                throw new IllegalArgumentException(

                        String.format("the value of the random number %d is not between 0 and 500", randomNumber));

            }

        } catch (NumberFormatException e) {

            throw new IllegalArgumentException(

                    String.format("the firt part '%s' of line '%s' is not an integer", parts[0], line));

        }

    }

}

输出:


Exception in thread "main" java.lang.IllegalArgumentException: the value of the random number 789 is not between 0 and 500



查看完整回答
反对 回复 2023-04-26
  • 3 回答
  • 0 关注
  • 117 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信