我正在使用 Java 解析用户输入的字符串,表示单个数值或范围。用户可以输入以下字符串:
10-19
10-19
他的意图是使用来自-->的整数10,11,12...19
用户还可以指定数字列表:
10,15,19
或以上组合:
10-19,25,33
是否有一种方便的方法(可能基于正则表达式)来执行此解析?或者我必须使用 拆分字符串String.split()
,然后手动迭代特殊符号(在这种情况下为“,”和“-”)?
我会这样做:
,
作为分隔符的拆分。^(\\d+)-(\\d+)$
,那么我知道我有一个范围。然后我会提取数字并创建我的范围(确保第一个数字低于第二个数字可能是个好主意,因为你永远不知道......)。然后你采取相应的行动。^\\d+$
我会知道我只有 1 个数字,所以我有一个特定的页面。然后我会采取相应的行动。这个经过测试(并经过充分评论)的正则表达式解决方案符合 OP 要求:
// 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.
'''
请注意,此解决方案仅演示了如何验证输入行以及如何从每行解析/提取值组件。它没有进一步验证对于范围值,第二个整数大于第一个整数。但是,可以轻松添加此逻辑检查。
编辑: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
.