0

我的输入是这样的:

line 1
**ER1.RIAA.SOMPSFIO(LIAOEE)         UTGD788  FDSJOFUZZÄ                                                                                                                                                                              line2      
JNDJZSDS ER1.RIAA.SIMEDFUA(AUDD)                YIRIHFIH1465EZZÄ     

line 3
UJZRJOERERÃLDE,UIE='UJ1.DHZKZ5.OZDEZN98.AAERRE',I=DZEDE                   POPZEOE**

我只想得到带有句点的字符,即:

ER1.RIAA.SOMPSFIO
ER1.RIAA.SIMEDFUA
UJ1.DHZKZ5.OZDEZN98.AAERRE

我的解决方案是:

try {
    StringBuilder sb = new StringBuilder();
    String line = br.readLine();

    while (line != null) {
        nrligne++;

int counter = 0;

for (int i=0; i<line.length(); i++ ) {
    if( line.charAt(i) == '.' ) {
        counter++;
    }
}

if (counter == 2) {

    if (line.matches("^.*[A-Z0-9]+\\..[A-Z1-9]+.*$")){

        line= removeTroublesomeCharacters(line);
        System.out.println("ligne vaut "+line);

        Pattern dsnPattern = Pattern.compile("^.*([A-Z0-9]+)\\..([A-Z1-9]+)\\..([A-Z1-9]+).*$");
        Matcher m = dsnPattern.matcher(line);

        if (m.matches()) {
            String part1   = m.group(1);
            String part2   = m.group(2);
            String part3   = m.group(3);

            System.out.println("part1 vaut "+part1);
            System.out.println("part2 vaut "+part2);
            System.out.println("part2 vaut "+part3);
        }               
    }

目前的结果是

ligne vaut ER1.RIAA.SOMPSFIO(LIAOEE)                                                                                             UTGD788
part1 vaut 1
part2 vaut IAA
part2 vaut OMPSFIO
ligne vaut PZFDSJOFUZZÃâ                                                                                                                                                                                    ER1.RIAA.SIMEDFUA(AUDD)                                                                                             UOOO88
part1 vaut 1
part2 vaut IAA
part2 vaut IMEDFUA
ligne vaut UJZRJOERERÃLDE,UIE='UJ1.DHZKZ5.OZDEZN98',I=DZEDE                                                                                                                                                                                                                                                                      POPZEOE
part1 vaut 1
part2 vaut HZKZ5
part2 vaut ZDEZN98

输入文件:http: //uploadhero.co/dl/PWBLhi7d 我不明白为什么正则表达式会吃掉每个字符的开头?有人可以帮我解决这个问题吗?

4

2 回答 2

1

由于您的表达的捕获部分之前和之后是“吃任何东西”.*表达,因此您希望捕获的部分内容最终会被这些“填充物”消耗掉。

您可以明确要求组前后的字符[A-Z0-9]+为非字母数字,如下所示:

   "^.*(?<![A-Z0-9])([A-Z0-9]+)\\.([A-Z1-9]+)\\.([A-Z1-9]+)(?![A-Z1-9]).*$"
  • (?<![A-Z0-9])表达式的意思是“前面没有[A-Z0-9]
  • (?![A-Z1-9])表达式的意思是“不跟随[A-Z1-9]

编辑 :

前瞻是不必要的,因为+它是贪婪的:

"^.*(?<![A-Z0-9])([A-Z0-9]+)\\.([A-Z1-9]+)\\.([A-Z1-9]+).*$"

(这归功于Rohit Jain

于 2013-10-09T21:35:10.293 回答
1

因为您在 , 之后消耗了一个额外的字符dot,而不是将其包含在字符类中。

\\..   // this will match a dot, and then following single character.

另外,.*将正则表达式开头的.*?. 由于量词默认是贪婪的,它们会消耗所有的字符,并且只在.要匹配的. 之前留下一个单词([a-z0-9]+)

将您的正则表达式更改为:

"^.*?([A-Z0-9]+)\\.([A-Z1-9]+)\\.([A-Z1-9]+).*$"

另外,由于您正在使用PatternMatcher无论如何,我会考虑使用该Matcher#find()方法,并为我需要的部分构建模式:

Pattern dsnPattern = Pattern.compile("([A-Z0-9]+)\\.([A-Z1-9]+)\\.([A-Z1-9]+)");
Matcher m = dsnPattern.matcher(line);

if (m.find()) {
于 2013-10-09T21:32:30.237 回答