【问题标题】:Extra white space when using regex in Scanner.useDelimiter()在 Scanner.useDelimiter() 中使用正则表达式时的额外空白
【发布时间】:2020-10-31 20:39:46
【问题描述】:

我正在尝试使用扫描仪从用户输入中读取文本文件,并在某些情况下分隔文件中的单词。必须对单词进行分隔的情况之一是单词在开头或结尾有撇号,但不应影响单词中的撇号。例如:如果扫描仪看到诸如 'tis 之类的单词,scanner.useDlmeter() 应该能够去掉撇号并留下单词“tis”,但如果它看到像“don't”这样的单词,那么它应该离开原样。

我正在使用正则表达式来涵盖分隔符应该用来分隔单词的多种情况。正则表达式正在做我需要的事情,但由于某种原因,我的结果是在有空格的单词之前打印出一个额外的空格,然后在单词的前面打印一个撇号。我是正则表达式的新手,我不知道如何解决这个问题,但任何建议都将不胜感激。

以下是我的文本文件中的文字:

'那是圣诞节的前一天晚上!但不要打开你的礼物。是 唯一的庆祝方式。

代码:

  public static void main (String[] args){
      Pattern p = Pattern.compile("[\\p{Punct}\\s&&[^']]+|('(?![\\w]))+|((?<![\\w])')+");
      System.out.println("Please enter a text file name.");
        
      Scanner sc = new Scanner(System.in);
        
      File file = new File(sc.nextLine());
        
      Scanner nSc = new Scanner(file);
        
      nSc.useDelimiter(p);
        
      while (nSc.hasNext()){
        
         String word = nSc.next().toLowerCase();
         System.out.println(word);
       
      }
      nSc.close();
}

预期:

twas 
the 
night 
before 
christmas 
but 
don't 
open 
your 
presents 
tis 
the 
only 
way 
to 
celebrate

实际:

twas 
the 
night 
before 
christmas 
but 
don't 
open 
your 
presents

tis 
the 
only 
way 
to 
celebrate

【问题讨论】:

  • 为什么要从 'twas 和 'tis 中删除 ',而 ' 的用途与 ' in don't 的用途完全相同?
  • 在“don't”中,撇号替换了字母“o”。在“'twas”中,撇号代替了字母“i”。

标签: java regex


【解决方案1】:

您可以使用regex'?\b\w+'?\w+\b 从字符串中获取所需的单词,然后将正则表达式'(.*) 替换为$1,其中$1 指定group(1)

import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String str = "'Twas the night before christmas! But don't open your presents. 'Tis the only way to celebrate.";
        List<String> list = Pattern.compile("'?\\b\\w+'?\\w+\\b")
                .matcher(str)
                .results()
                .map(r->r.group().replaceAll("'(.*)", "$1"))
                .collect(Collectors.toList());

        System.out.println(list);
    }
}

输出:

[Twas, the, night, before, christmas, But, dont, open, your, presents, Tis, the, only, way, to, celebrate]

正则表达式的解释,'?\b\w+'?\w+\b:

  1. \b 指定 word boundary
  2. \w+ 指定 one or more word character
  3. '? 指定可选 '

如果你不熟悉Stream API,你可以这样做:

Scanner nSc = new Scanner(file);
while (nSc.hasNextLine()) {
    String line = nSc.nextLine().toLowerCase();
    Pattern pattern = Pattern.compile("'?\\b\\w+'?\\w+\\b");
    Matcher matcher = pattern.matcher(line);
    while (matcher.find()) {
        String word = matcher.group();
        System.out.println(word.replaceAll("'(.*)", "$1"));
    }
}
nSc.close();

【讨论】:

  • 感谢您的帮助,这主要是我想要的,但是我仍然需要保留前面带有撇号的单词。所以像“'twas”这样的词变成了“twas”
  • @ssang - 我已根据此说明更新了答案。如有任何疑问/问题,请随时发表评论。
猜你喜欢
  • 2014-04-12
  • 2013-07-26
  • 1970-01-01
  • 2016-02-29
  • 2017-05-09
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多