从字符串高级解析数值范围

我正在使用Java来解析用户输入的字符串,表示单个数值或范围。 用户可以输入以下字符串:

10-19 

他的目的是使用10-19 – > 10,11,12...19整数

用户还可以指定数字列表:

 10,15,19 

或者上面的组合:

 10-19,25,33 

是否有一个方便的方法,可能基于正则表达式,来执行此解析? 或者我必须使用String.split()拆分字符串,然后手动迭代特殊符号(在这种情况下为’,’和’ – ‘)?

我就是这样做的:

  1. 使用,作为分隔符拆分。
  2. 如果它匹配这个正则表达式: ^(\\d+)-(\\d+)$ ,那么我知道我有一个范围。 然后我会提取数字并创建我的范围(确保第一个数字低于第二个数字可能是一个好主意,因为你永远不知道……)。 然后你采取相应行动。
  3. 如果它匹配这个正则表达式: ^\\d+$我会知道我只有一个数字,所以我有一个特定的页面。 然后我会采取相应的行动。

这个经过测试(并且完全注释)的正则表达式解决方案符合OP要求:

Java正则表达式解决方案

 // TEST.java 20121024_0700 import java.util.regex.*; public class TEST { public static Boolean isValidIntRangeInput(String text) { Pattern re_valid = Pattern.compile( "# Validate comma separated integers/integer ranges.\n" + "^ # Anchor to start of string. \n" + "[0-9]+ # Integer of 1st value (required). \n" + "(?: # Range for 1st value (optional). \n" + " - # Dash separates range integer. \n" + " [0-9]+ # Range integer of 1st value. \n" + ")? # Range for 1st value (optional). \n" + "(?: # Zero or more additional values. \n" + " , # Comma separates additional values. \n" + " [0-9]+ # Integer of extra value (required). \n" + " (?: # Range for extra value (optional). \n" + " - # Dash separates range integer. \n" + " [0-9]+ # Range integer of extra value. \n" + " )? # Range for extra value (optional). \n" + ")* # Zero or more additional values. \n" + "$ # Anchor to end of string. ", Pattern.COMMENTS); Matcher m = re_valid.matcher(text); if (m.matches()) return true; else return false; } public static void printIntRanges(String text) { Pattern re_next_val = Pattern.compile( "# extract next integers/integer range value. \n" + "([0-9]+) # $1: 1st integer (Base). \n" + "(?: # Range for value (optional). \n" + " - # Dash separates range integer. \n" + " ([0-9]+) # $2: 2nd integer (Range) \n" + ")? # Range for value (optional). \n" + "(?:,|$) # End on comma or string end.", Pattern.COMMENTS); Matcher m = re_next_val.matcher(text); String msg; int i = 0; while (m.find()) { msg = " value["+ ++i +"] ibase="+ m.group(1); if (m.group(2) != null) { msg += " range="+ m.group(2); }; System.out.println(msg); } } public static void main(String[] args) { String[] arr = new String[] { // Valid inputs: "1", "1,2,3", "1-9", "1-9,10-19,20-199", "1-8,9,10-18,19,20-199", // Invalid inputs: "A", "1,2,", "1 - 9", " ", "" }; // Loop through all test input strings: int i = 0; for (String s : arr) { String msg = "String["+ ++i +"] = \""+ s +"\" is "; if (isValidIntRangeInput(s)) { // Valid input line System.out.println(msg +"valid input. Parsing..."); printIntRanges(s); } else { // Match attempt failed System.out.println(msg +"NOT valid input."); } } } } 

输出:

 r''' String[1] = "1" is valid input. Parsing... value[1] ibase=1 String[2] = "1,2,3" is valid input. Parsing... value[1] ibase=1 value[2] ibase=2 value[3] ibase=3 String[3] = "1-9" is valid input. Parsing... value[1] ibase=1 range=9 String[4] = "1-9,10-19,20-199" is valid input. Parsing... value[1] ibase=1 range=9 value[2] ibase=10 range=19 value[3] ibase=20 range=199 String[5] = "1-8,9,10-18,19,20-199" is valid input. Parsing... value[1] ibase=1 range=8 value[2] ibase=9 value[3] ibase=10 range=18 value[4] ibase=19 value[5] ibase=20 range=199 String[6] = "A" is NOT valid input. String[7] = "1,2," is NOT valid input. String[8] = "1 - 9" is NOT valid input. String[9] = " " is NOT valid input. String[10] = "" is NOT valid input. ''' 

请注意,此解决方案仅演示如何validation输入行以及如何从每行解析/提取值组件。 它没有进一步validation对于范围值,第二个整数大于第一个整数。 但是,可以轻松添加此逻辑检查。

编辑次数:2012-10-24 07:00固定索引i从零开始计算。

您可以使用

 strinput = '10-19,25,33' eval(cat(2,'[',strrep(strinput,'-',':'),']')) 

最好是包含一些输入检查,负数也会给这个方法带来问题。

在最简单的方法中,您可以使用邪恶的eval

 A = eval('[10:19,25,33]') A = 10 11 12 13 14 15 16 17 18 19 25 33 

当然,在你这样做之前,你应该三思而后行。 特别是如果这是用户提供的字符串! 想象一下如果用户提供任何其他命令会发生什么……

 eval('!rm -rf /') 

你必须确保除了你想要的东西之外别无其他。 你可以通过regexp来做到这一点。