【问题标题】:How to make program output whole words with Pattern and Matcher如何使用 Pattern 和 Matcher 使程序输出整个单词
【发布时间】:2020-05-01 05:35:32
【问题描述】:

我有一个文本(例如"All Java programmers program good programs."),需要输出所有包含program 的单词。

Pattern pattern = Pattern.compile("program");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
    System.out.println(matcher.start() + " " + extractWord(matcher.start(), text));
}

我可以写一个Pattern,它将整个找到诸如“程序员”之类的词作为Matcher结果吗?

我自己编写了extractWord 方法:

public static String extractWord(int start, String line) {
    int n = 0;
    while (start + n < line.length()) {
        if (line.charAt(start + n) == ' ' || line.charAt(start + n) == '.') {
            break;
        } else {
            n++;
        }
    }
    return line.substring(start, start + n);
}

但我不喜欢这样做。

【问题讨论】:

    标签: java regex


    【解决方案1】:

    一个简单的解决方案是将您的正则表达式更改为\w*program\w*。这将匹配包含program 的任何单词以及由单词字符(即字母、数字和下划线)组成的任何可能的前缀和后缀。然后,使用matcher.group() 检索匹配器找到的匹配项。

    更高级的方法是使用正则表达式[a-z]*program[a-z]*。这将匹配包含program 的任何单词以及仅由字母组成的任何可能的前缀和后缀。 Pattern.CASE_INSENTITIVE 标志匹配大小写字母。

    Java (OpenJDK 8),856 字节

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Main
    {
        public static final String simpleText = "All Java programmers program good programs.";
        public static final String complexText = "All Java deProGraMMers Program good pRoGrAmS.";
    
        public static void main(String[] args)
        {
            System.out.println("Groups for '" + simpleText + "':");
            printGroups(simpleText);
            System.out.println("Groups for '" + complexText + "':");
            printGroups(complexText);
        }
    
        private static void printGroups(String text)
        {
            String regex = "[a-z]*program[a-z]*";
            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(text);
            while (matcher.find())
            {
                System.out.println(matcher.group());
            }
        }
    }
    

    执行输出:

     Groups for 'All Java programmers program good programs.':
     programmers
     program
     programs
     
     Groups for 'All Java deProGraMMers Program good pRoGrAmS.':
     deProGraMMers
     Program
     pRoGrAmS
    

    Try it online!

    【讨论】:

    • 1) 问题说“有程序inside的单词”deprogram 怎么样? --- 2) Program 怎么样? --- 3) 为什么是捕获组?你甚至没有使用它。 --- 4) program_42 是一个词吗?在编程中,它是一个标识符,但它是一个“词”吗?
    • @Andreas 感谢您的 cmets。我将根据您的观点编辑答案,但我们可能想听听 OP 的考虑。
    • CASE_INSENSITIVE 标志不适合包含在您的解决方案中吗?
    • @Abra 是的,非常合适,谢谢指出!
    【解决方案2】:

    我希望我们使用String.contains() 方法:

    String str = "All Java programmers program good programs.";
    String[] arr = str.split(" ");
    for (String s : arr)
        if(s.contains("program"))
            System.out.println(s);
    
    //output: 
    //programmers
    //program
    //programs.
    

    【讨论】:

    • 这并没有按照 OP 的要求使用 PatternMatcher
    • 是的。第一个答案更好
    • @HasmikGaryaka 如果它解决了您的问题,那么请不要忘记将其标记为已接受的答案。
    【解决方案3】:

    试试这个正则表达式:\b\w*program\w*\b..

    • \b -- 表示以单词边界开头
    • \w* -- 表示可以有0个或多个单词字符
    • program -- 匹配程序
    • \w* -- 表示可以有0个或多个单词字符
    • \b -- 表示以单词边界结尾

    代码:

    String text = "All Java programmers program good programs.";
    Pattern pattern = Pattern.compile("\\b\\w*program\\w*\\b");
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2011-06-13
      • 2012-06-10
      • 2021-02-01
      相关资源
      最近更新 更多