[英]Parsing text using Regex
所以我试图解析一个包含两个关键组成部分的字符串。 一个告诉我时间选择,另一个告诉我位置。
这是文本的样子
KB_H9Oct4GFP_20130305_p00{iiii}t00000{ttt}z001c02.tif
{iiii}
是头寸, {ttt}
是时间选项。
我需要将{ttt}
和{iiii}
分开,以便获得完整的文件名:例如,位置1和时间片1 = KB_H9Oct4GFP_20130305_p0000001t000000001z001c02.tif
到目前为止,这里是我解析它们的方式:
int startTimeSlice = 1;
int startTile = 1;
String regexTime = "([^{]*)\\{([t]+)\\}(.*)";
Pattern patternTime = Pattern.compile(regexTime);
Matcher matcherTime = patternTime.matcher(filePattern);
if (!matcherTime.find() || matcherTime.groupCount() != 3)
{
throw new IllegalArgumentException("Incorect filePattern: " + filePattern);
}
String timePrefix = matcherTime.group(1);
int tCount = matcherTime.group(2).length();
String timeSuffix = matcherTime.group(3);
String timeMatcher = timePrefix + "%0" + tCount + "d" + timeSuffix;
String timeFileName = String.format(timeMatcher, startTimeSlice);
String regex = "([^{]*)\\{([i]+)\\}(.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(timeFileName);
if (!matcher.find() || matcher.groupCount() != 3)
{
throw new IllegalArgumentException("Incorect filePattern: " + filePattern);
}
String prefix = matcher.group(1);
int iCount = matcher.group(2).length();
String suffix = matcher.group(3);
String nameMatcher = prefix + "%0" + iCount + "d" + suffix;
String fileName = String.format(nameMatcher, startTile);
不幸的是,我的代码无法正常工作,并且在检查第二个matcher
是否在timeFileName
找到任何内容时timeFileName
。
在进行第一次正则表达式检查后,它得到以下内容作为timeFileName
: 000000001z001c02.tif
,因此它将切断包括{iiii}
在内的开头部分。
不幸的是,我不能假设哪个组先进入( {iiii}
或{ttt}
),所以我试图设计一个解决方案,该解决方案首先处理{ttt}
,然后处理{iiii}
。
另外,这是我也在尝试解析的有效文本的另一个示例: F_{iii}_{ttt}.tif
遵循的步骤:
这是代码:
String filePattern = "KB_H9Oct4GFP_20130305_p00{iiii}t00000{ttt}z001c02.tif";
int startTimeSlice = 1;
int startTile = 1;
Pattern patternTime = Pattern.compile("(\\{[t]*\\})");
Matcher matcherTime = patternTime.matcher(filePattern);
if (matcherTime.find()) {
String timePattern = matcherTime.group(0);// {ttt}
NumberFormat timingFormat = new DecimalFormat(timePattern.replaceAll("t", "0")
.substring(1, timePattern.length() - 1));// 000
Pattern patternPosition = Pattern.compile("(\\{[i]*\\})");
Matcher matcherPosition = patternPosition.matcher(filePattern);
if (matcherPosition.find()) {
String positionPattern = matcherPosition.group(0);// {iiii}
NumberFormat positionFormat = new DecimalFormat(positionPattern
.replaceAll("i", "0").substring(1, positionPattern.length() - 1));// 0000
System.out.println(filePattern.replace(timePattern,
timingFormat.format(startTimeSlice)).replace(positionPattern,
positionFormat.format(startTile)));
}
}
您的第一个模式如下所示:
String regexTime = "([^{]*)\\{([t]+)\\}(.*)";
这将找到一个字符串,该字符串由零个或多个非{
字符组成,然后由{t...t}
,然后是其他字符组成。
当您输入
KB_H9Oct4GFP_20130305_p00{iiii}t00000{ttt}z001c02.tif
匹配的第一个子字符串是
iiii}t00000{ttt}z001c02.tif
i之前的{
无法匹配,因为您告诉它只能匹配非{
字符。 结果是,当您重新iiii}
字符串以进行第二次匹配时,它将以iiii}
开头,因此不会像您尝试的那样匹配{iiii}
。
当您寻找{ttt...}
,我看不出有任何理由从字符串的第一部分中排除{
或其他任何字符。 因此将正则表达式更改为
"^(.*)\\{(t+\\}(.*)$"
可能是解决此问题的简单方法。 注意,如果要确保在组中包括字符串的整个开头和字符串的整个结尾,则应包括^
和$
以分别匹配字符串的开头和结尾; 否则,匹配器引擎可能会决定不包括所有内容。 在这种情况下,它不会,但是无论如何都是一个好习惯,因为这使事情变得很明确,并且不需要任何人知道“贪婪”和“勉强”匹配之间的区别。 或者使用matches()
而不是find()
,因为matches()
自动尝试匹配整个字符串。
好的,因此,经过一些测试,我找到了一种处理这种情况的方法:
为了解析{ttt}
我可以使用正则表达式: (.*)\\\\{t([t]+)\\\\}(.*)
现在,这意味着我必须将tCount加1才能说明从\\\\{t
{iii}
: (.*)\\\\{i([i]+)\\\\}(.*)
也许更简单的方法(如http://regex101.com/r/vG7kY7所确认)是
(\{i+\}).*(\{t+\})
您不需要在要匹配的单个字符周围使用[]
。 把事情简单化。 i+
表示“一个或多个i
”,只要按给定的顺序进行,该表达式即可工作(第一个匹配项为{iiii}
,第二个匹配项为{ttttt}
)。
在字符串中编写时,可能需要转义反斜杠...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.