使用正则表达式从文本中删除连续重复的单词并显示新文本
Posted
技术标签:
【中文标题】使用正则表达式从文本中删除连续重复的单词并显示新文本【英文标题】:Removing consecutive duplicates words out of text using Regex and displaying the new text 【发布时间】:2014-07-06 09:05:15 【问题描述】:喂,
我有以下代码:
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.*;
/
public class RegexSimple4
public static void main(String[] args)
try
Scanner myfis = new Scanner(new File("D:\\myfis32.txt"));
ArrayList <String> foundaz = new ArrayList<String>();
ArrayList <String> noduplicates = new ArrayList<String>();
while(myfis.hasNext())
String line = myfis.nextLine();
String delim = " ";
String [] words = line.split(delim);
for (String s : words)
if (!s.isEmpty() && s != null)
Pattern pi = Pattern.compile("[aA-zZ]*");
Matcher ma = pi.matcher(s);
if (ma.find())
foundaz.add(s);
if(foundaz.isEmpty())
System.out.println("No words have been found");
if(!foundaz.isEmpty())
int n = foundaz.size();
String plus = foundaz.get(0);
noduplicates.add(plus);
for(int i=1; i<n; i++)
if ( !noduplicates.get(i-1) .equalsIgnoreCase(foundaz.get(i)))
noduplicates.add(foundaz.get(i));
//System.out.print("Cuvantul/cuvintele \n"+i);
if(!foundaz.isEmpty())
System.out.print("Original text \n");
for(String s: foundaz)
System.out.println(s);
if(!noduplicates.isEmpty())
System.out.print("Remove duplicates\n");
for(String s: noduplicates)
System.out.println(s);
catch(Exception ex)
System.out.println(ex);
目的是从短语中删除连续重复。该代码仅适用于一列字符串,不适用于全长短语。
例如我的输入应该是:
Blah blah 狗猫老鼠。 猫鼠狗狗。
还有输出
Blah 狗猫老鼠。 猫鼠狗。
此致,
【问题讨论】:
【参考方案1】:首先,正则表达式[aA-zZ]*
并没有按照您的想法执行。这意味着“匹配零个或多个a
s 或ASCII A
和ASCII z
之间范围内的字符(还包括[
、]
、\
等)或Z
s ”。因此它也匹配空字符串。
假设您只查找仅由 ASCII 字母组成的重复单词,不区分大小写,保留第一个单词(这意味着您不想匹配 "it's it's"
或 "olé olé!"
),那么您可以在单个正则表达式操作中执行此操作:
String result = subject.replaceAll("(?i)\\b([a-z]+)\\b(?:\\s+\\1\\b)+", "$1");
会改变的
Hello hello Hello there there past pastures
进入
Hello there past pastures
说明:
(?i) # Mode: case-insensitive
\b # Match the start of a word
([a-z]+) # Match one ASCII "word", capture it in group 1
\b # Match the end of a word
(?: # Start of non-capturing group:
\s+ # Match at least one whitespace character
\1 # Match the same word as captured before (case-insensitively)
\b # and make sure it ends there.
)+ # Repeat that as often as possible
看live on regex101.com。
【讨论】:
但是我如何在我的程序中使用你的正则表达式。我有一个文件作为输入,我想使用 System.out.print 显示它的内容而没有冗余。谢谢你:-) 非常感谢,但是 $1 是什么意思 :-)? @SocketM:这是一个特殊变量,它引用了第一个 capturing group 的内容,在这种情况下是第一个单词(我们要保留)。 @TimPietzcker 我也有同样的问题。你能帮我检查一下我的问题吗? QUESTION LINK 。 fvbuendia 回答了我的问题,但他的回答还不够,因为删除重复功能不起作用。我正在寻找解决方案,但我不能。【参考方案2】:下面是您的代码。我使用了行来分割文本和 Tim 的正则表达式。
import java.util.Scanner;
import java.io.*;
import java.util.regex.*;
import java.util.ArrayList;
/**
*
* @author Marius
*/
public class RegexSimple41
/**
* @param args the command line arguments
*/
public static void main(String[] args)
ArrayList <String> manyLines = new ArrayList<String>();
ArrayList <String> noRepeat = new ArrayList<String>();
try
Scanner myfis = new Scanner(new File("D:\\myfis41.txt"));
while(myfis.hasNext())
String line = myfis.nextLine();
String delim = System.getProperty("line.separator");
String [] lines = line.split(delim);
for(String s: lines)
if(!s.isEmpty()&&s!=null)
manyLines.add(s);
if(!manyLines.isEmpty())
System.out.print("Original text\n");
for(String s: manyLines)
System.out.println(s);
if(!manyLines.isEmpty())
for(String s: manyLines)
String result = s.replaceAll("(?i)\\b([a-z]+)\\b(?:\\s+\\1\\b)+", "$1");
noRepeat.add(result);
if(!noRepeat.isEmpty())
System.out.print("Remove duplicates\n");
for(String s: noRepeat)
System.out.println(s);
catch(Exception ex)
System.out.println(ex);
祝你好运,
【讨论】:
【参考方案3】:下面的代码工作正常
导入 java.util.Scanner;
导入 java.util.regex.Matcher;
导入 java.util.regex.Pattern;
公共类 DuplicateRemoveEx
public static void main(String[] args)
String regex="(?i)\\b(\\w+)(\\b\\W+\\1\\b)+";
Pattern p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
Scanner in = new Scanner(System.in);
int numSentences = Integer.parseInt(in.nextLine());
while(numSentences-- >0)
String input = in.nextLine();
Matcher m = p.matcher(input);
while(m.find())
input=input.replaceAll(regex, "$1");
System.out.println(input);
in.close();
【讨论】:
谢谢。 Java 是一头奇怪的野兽。发送编译时不区分大小写的标志,但 (?i) 也在正则表达式中!以上是关于使用正则表达式从文本中删除连续重复的单词并显示新文本的主要内容,如果未能解决你的问题,请参考以下文章
使用正则表达式删除单词中的空格 - 用于文本挖掘的预处理数据