2014-03-04 50 views
0

所以我想解析包含两个关键组件的字符串。一个告诉我时间选择,另一个是位置。使用正则表达式解析文本

以下是文字看起来像

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中找到任何东西时失败。

第一正则表达式检查后得到以下作为timeFileName000000001z001c02.tif,因此它被切断开始药剂包括{iiii}

可惜我不能假设该组先行({iiii}{ttt}),所以我我试图设计一个解决方案,首先处理{ttt},然后处理{iiii}

而且,这里是有效的文本的另一个例子,我也试图解析:F_{iii}_{ttt}.tif

+0

他们都有拖尾“T”和“Z”字来区分哪些是应该的顺序变化?你的最后一个例子看起来像't'和'z'在某些情况下可能不存在。 –

+0

确实难以保证z和t与最后一个例子'F_ {iii} _ {ttt} .tif' – Jameshobbs

+0

是否是正则表达式的一个要求? – Solace

回答

1

遵循的步骤:

  • 查找字符串{TTT ...}在文件名
  • 形式字符串基于无 “T” 的数字格式
  • 查找字符串{IIII ...}在文件名
  • 表基于无方法的“i”的字符串
  • 使用与string.replace()的数字格式,以取代时间和立场

下面是代码:

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))); 
    } 
} 
0

你的第一个模式是这样的:

String regexTime = "([^{]*)\\{([t]+)\\}(.*)"; 

此发现由零序列的字符串或更多非{个字符,其次是{t...t},其后是其他字符。

当你输入

KB_H9Oct4GFP_20130305_p00{iiii}t00000{ttt}z001c02.tif 

第一个匹配的字符串是

iiii}t00000{ttt}z001c02.tif 

{的无法比拟的我之前,因为你告诉它只是非{字符匹配。结果是,当您重新组成字符串进行第二次匹配时,它将以iiii}开头,因此不会像您正在尝试的那样匹配{iiii}

当您在寻找{ttt...}时,我看不到有任何理由排除{或字符串第一部分中的任何其他字符。所以改变正则表达式为

"^(.*)\\{(t+\\}(.*)$" 

可能是一个简单的方法来解决这个问题。请注意,如果要确保将字符串的整个开头和字符串的整个末尾包括在组中,则应该分别包含^$以匹配字符串的开头和结尾;否则匹配器引擎可能决定不包含所有内容。在这种情况下,它不会,但无论如何都是一个好习惯,因为这会让事情变得明确,并且不需要任何人知道“贪婪”和“不情愿”匹配之间的区别。或者使用matches()而不是find(),因为matches()会自动尝试匹配整个字符串。

+0

对不起,我在上面的正则表达式中有一个错字。我将编辑并删除'。 '不是我的原始代码。 – Jameshobbs

0

好了,所以有点测试后,我找到了一种方法来处理这种情况:

为了解析这些{ttt}我可以使用正则表达式:(.*)\\{t([t]+)\\}(.*)

现在,这意味着我有一个递增TCOUNT考虑到我从\\{t

同抢的T无二{iii}(.*)\\{i([i]+)\\}(.*)

+0

为什么增加一个?只要移动左括号:'(t [t] +)',现在它将捕获组中的所有't'。或'(t {2,})'匹配两个或更多't's。顺便说一句,除非你认为它更具可读性,否则没有理由将单个字符放在方括号中。 – ajb

+0

确实你是对的。这是一个包含所有内容的更多最终版本。 '(。*)(\\ {[I] + \\})(。*)' – Jameshobbs

0

也许更简单的方式来做到这一点(由http://regex101.com/r/vG7kY7证实)是

(\{i+\}).*(\{t+\}) 

你不需要[]你身边的匹配单个字符。把事情简单化。 i+的意思是“一个或多个i”,并且只要这些是按照给定的顺序,这个表达式将起作用(第一个匹配是{iiii}和第二个{ttttt})。

您可能需要在一个字符串写入时,转义反斜线...