正则表达式从匹配java代码中排除单词

时间:2014-11-30 07:51:41

标签: java regex

也许有人可以帮助我。我试图在java代码中包含一个正则表达式来匹配除ZZ78之外的所有字符串。我想知道我的正则表达式中缺少什么。

输入字符串是str =“ ab57cdZZ78efghZZ7ij @ klmZZ78noCODpqrZZ78stuvw27z @ xyzZZ78

我正在试用这个正则表达式(?:(?![ZZF8])。)* 但是如果你在http://regexpal.com/进行测试 这个正则字符串反对字符串,你会发现它没有完全正常工作。

str = new String ("ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78");
Pattern pattern = Pattern.compile("(?:(?![ZZ78]).)*");

匹配的字符串应为

ab57cd
efghZZ7ij@klm
noCODpqr
stuvw27z@xyz

更新

Hello Avinash Raj和Chthonic Project。非常感谢您提供的帮助和解决方案。

我最初使用split方法,但我试图避免得到空字符串 例如,当分隔符字符串位于主字符串的开头或结尾时。

然后,我认为正则表达式可以帮助我提取除“ZZ78”以外的所有内容,以此方式避免 输出结果为空。

下面我展示使用split方法(Chthonic's)和regex(Avinash's)的代码都生成空 如果未使用注释的“if()”条件,则为字符串。

使用那些“if()”是不打印空字符串的唯一方法吗?或者可能是正则表达式 调整了一点以匹配非空字符串?

这是我到目前为止测试的代码:

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class RegexTest {
        public static void main(String[] args) {
            System.out.println("########### Matches with Split ###########");
            String str = "ZZ78ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
            for (String s : str.split("ZZ78")) {
                //if ( !s.isEmpty() ) {
                    System.out.println("This is a match <<" + s  + ">>");
                //} 
            }
            System.out.println("##########################################");

            System.out.println("########### Matches with Regex ###########");
            String s = "ZZ78ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
            Pattern regex = Pattern.compile("((?:(?!ZZ78).)*)(ZZ78|$)");
            Matcher matcher = regex.matcher(s);
            while(matcher.find()){
                //if ( !matcher.group(1).isEmpty() ) { 
                    System.out.println("This is a match <<" + matcher.group(1) + ">>");
                //}    
            }
        }
    }

**and the output (without use the "if()´s"):**
########### Matches with Split ###########
This is a match <<>>
This is a match <<ab57cd>>
This is a match <<efghZZ7ij@klm>>
This is a match <<noCODpqr>>
This is a match <<stuvw27z@xyz>>
##########################################
########### Matches with Regex ###########
This is a match <<>>
This is a match <<ab57cd>>
This is a match <<efghZZ7ij@klm>>
This is a match <<noCODpqr>>
This is a match <<stuvw27z@xyz>>
This is a match <<>>

到目前为止,感谢您的帮助。

提前致谢

更新#2:

优秀的答案和解决方案。现在它非常好用。这是我用两种解决方案测试的最终代码。

再次感谢。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {
    public static void main(String[] args) {
        System.out.println("########### Matches with Split ###########");
        String str = "ZZ78ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
        Arrays.stream(str.split("ZZ78")).filter(s -> !s.isEmpty()).forEach(System.out::println);

        System.out.println("##########################################");

        System.out.println("########### Matches with Regex ###########");
        String s = "ZZ78ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
        Pattern regex = Pattern.compile("((?:(?!ZZ78).)*)(ZZ78|$)");
        Matcher matcher = regex.matcher(s);
        ArrayList<String> allMatches = new ArrayList<String>();
        ArrayList<String> list = new ArrayList<String>();
        while(matcher.find()){
            allMatches.add(matcher.group(1));
        }
        for (String s1 : allMatches)
            if (!s1.equals(""))
                list.add(s1);

        System.out.println(list);
    }
}

And output:
########### Matches with Split ###########
ab57cd
efghZZ7ij@klm
noCODpqr
stuvw27z@xyz
##########################################
########### Matches with Regex ###########
[ab57cd, efghZZ7ij@klm, noCODpqr, stuvw27z@xyz]

2 个答案:

答案 0 :(得分:4)

最简单的方法如下:

public static void main(String[] args) {
    String str = "ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
    for (String s : str.split("ZZ78"))
        System.out.println(s);
}

正如预期的那样,输出是:

ab57cd
efghZZ7ij@klm
noCODpqr
stuvw27z@xyz

如果用于分割字符串的模式位于开头(即示例代码中的“ZZ78”),则返回的第一个元素将是一个空字符串,正如您已经注意到的那样。为避免这种情况,您需要做的就是过滤数组。这与放置if基本相同,但您可以通过这种方式避免额外的条件行。我会这样做(在Java 8中):

String test_str = ...; // whatever string you want to test it with
Arrays.stream(str.split("ZZ78")).filter(s -> !s.isEmpty()).foreach(System.out::println);

答案 1 :(得分:2)

您必须删除字符类,因为[ZZ78]匹配给定列表中的单个charcater。仅(?:(?!ZZ78).)*不会给你想要的比赛。将此ab57cdZZ78视为输入字符串。首先,此(?:(?!ZZ78).)*匹配字符串ab57cd,然后它会尝试匹配以下Z并检查条件(?!ZZ78),这意味着匹配任何字符但不匹配{{1} }。因此,它很容易匹配以下ZZ78,接下来正则表达式引擎移动到下一个字符Z并检查此Z条件。由于第二个(?!ZZ78)后面没有Z,因此Z78与正则表达式引擎相匹配。

Z

<强>输出:

String s = "ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
Pattern regex = Pattern.compile("((?:(?!ZZ78).)*)(ZZ78|$)");
Matcher matcher = regex.matcher(s);
while(matcher.find()){
        System.out.println(matcher.group(1));
}

<强>解释

  • ab57cd efghZZ7ij@klm noCODpqr stuvw27z@xyz 捕获((?:(?!ZZ78).)*)零次或多次的任何角色。
  • ZZ78并且还会将以下(ZZ78|$)或行锚的结尾捕获到第2组。
  • 组索引1包含ZZ78
  • 以外的单个或一组字符

<强>更新

ZZ78

<强>输出:

String s = "ZZ78ab57cdZZ78efghZZ7ij@klmZZ78noCODpqrZZ78stuvw27z@xyzZZ78";
Pattern regex = Pattern.compile("((?:(?!ZZ78).)*)(ZZ78|$)");
Matcher matcher = regex.matcher(s);
ArrayList<String> allMatches = new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
while(matcher.find()){
    allMatches.add(matcher.group(1));
}
for (String s1 : allMatches)
    if (!s1.equals(""))
        list.add(s1);

System.out.println(list);