我需要处理一些错过撇号的句子。
例如:
项目是假的。卖方声称它真实且不是
它是假的没有照片你不能看到马林鱼,发回等待退款。
如何使用正则表达式来查找“不能”,“不能”,“没有”,“不是”,“它是”等等。
注意:
“它s”和“不能”在这里可能会很棘手。
例如:
“我不能一个故事”v.s. “我不能现在做任何事情”
我们不应该在第一句中添加撇号
答案 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 t
和Don 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是任何非单词字母 +是一次或多次出现