正则表达式找到“can t”,“haven t”等等并添加撇号

时间:2017-03-28 06:32:54

标签: java regex

我需要处理一些错过撇号的句子。

例如:

  1. 项目是假的。卖方声称真实且不是

  2. 它是假的没有照片你不能看到马林鱼,发回等待退款。

  3. 如何使用正则表达式来查找“不能”,“不能”,“没有”,“不是”,“它是”等等。

    注意:

    “它s”和“不能”在这里可能会很棘手。

    例如:

    “我不能一个故事”v.s. “我不能现在做任何事情”

    我们不应该在第一句中添加撇号

5 个答案:

答案 0 :(得分:9)

我建议你不要试图在这里进行正则表达式奥运会,而是用正确的替换品替换每个破损的收缩。您可以定义一个地图,将每个损坏的收缩映射到其替换。然后,迭代该地图并将每个修正应用于您要更正的文本。

String input = "I can t do it because it s not raining and it doesn t make sense.";
Map<String, String> cnts = new HashMap<>();
cnts.put("doesn t", "doesn't");
cnts.put("can t", "can't");
cnts.put("haven t", "haven't");
cnts.put("aren t", "aren't");
cnts.put("it s", "it's");
cnts.put("isn t", "isn't");
for (Map.Entry<String, String> entry : cnts.entrySet()) {
    String start = entry.getKey();
    String end = entry.getValue();
    input = input.replaceAll("\\b" + start + "\\b", end);
}
System.out.println(input);

<强>输出:

I can't do it because it's not raining and it doesn't make sense.

答案 1 :(得分:2)

不是执行多个replaceAll()调用,而是使用appendReplacement()appendTail()编写替换循环,在文本的单次迭代中完成所有操作。

为了防止像“我可以讲故事”这样的棘手案例,请使用\b word-boundary构造,该构造在Java字符串文字中为"\\b"

您还希望正则表达式不区分大小写,因此don tDon t都会得到修复。这可以使用CASE_INSENSITIVE标志来完成,也可以在正则表达式中以(?i)的形式给出。

private static String fixApostrophe(String input) {
    StringBuffer buf = new StringBuffer(input.length());
    Matcher m = Pattern.compile("(?i)\\b(?:aren t" +
                                         "|can t" +
                                         "|doesn t" +
                                         "|haven t" +
                                         "|isn t" +
                                         "|it s" +
                                         ")\\b").matcher(input);
    while (m.find())
        m.appendReplacement(buf, m.group().replace(' ', '\''));
    return m.appendTail(buf).toString();
}

测试

System.out.println(fixApostrophe("item is a fake. seller claims it s genuine and it isn t"));
System.out.println(fixApostrophe("it s fake and has no photo you can t see marlin, sent it back awaiting refund."));
System.out.println(fixApostrophe("I can tell a story"));
System.out.println(fixApostrophe("I can t do anything now"));

输出

item is a fake. seller claims it's genuine and it isn't
it's fake and has no photo you can't see marlin, sent it back awaiting refund.
I can tell a story
I can't do anything now

答案 2 :(得分:1)

这个正则表达式怎么样?

\bcan t\b

然后你可以替换空间。

您可以类似地为其他单词构建正则表达式。

答案 3 :(得分:0)

让我们来这里试试一下小正则表达式奥运会:)

replaceAll("(don|is|isn|hasn|haven)(?: +)(\\b[s,t]\\b)", "\\1'\\2")

String text = "I don t like what hasn t been written";
text.replaceAll("(don|is|isn|hasn|haven)(?: +)(\\b[s,t]\\b)", "\\1'\\2");

输出:

  

我不喜欢没有写过的东西

免责声明:没有运行代码,它可能包含语法错误(尽管它不应该)。

现在你可以生成部分

(don|is|isn|hasn|haven)

以编程方式包含所有需要处理的案例。

答案 4 :(得分:0)

更通用(不确定您是否希望它是通用的):

yourText.replaceAll("(\\w+) (\\w)\\b", "\\1'\\2");

这适用于任何something x:一个或多个单词字母(something),后跟空格和单个字母(x)。

括号引入可以在替换表达式中使用\ i引用的组(i是组的编号,从左侧开始,为1)。

\ w是任何单词字母 \ W是任何非单词字母 +是一次或多次出现