我正在努力提高效率,对我来说很光鲜。
我正在处理的问题是,如果该结尾位于特定列表中,我需要删除结尾一词。
即假设列表是:
{ical, ic,ion,ogy} //the actual list is a handful of elements (almost ~20)
当我遇到这样的句子时,我需要做的是:
Hello world, this sentence is magic. Because we will talk about Biology.
它将缩减为:
Hello world, this sentence is **mag** . Because we will talk about **Biol** .
最简单的方法是迭代句子中的单词,并检查每个结尾是否与列表中的元素匹配......但这非常昂贵。
有没有更简单的方法来实现上述目标?
* ALSO *
您可以使用一个大型REGEX执行此操作:
(?<=([a-zA-Z]))(ic|ical|ics|raphy|raphic|raphical|ion|ions|ional|ive|ivity|ity|ities|ische|ischen|ischer|isches|ogy|ogic|ogical|omy|omic|omics|omical)(?=(\b))
答案 0 :(得分:4)
简单方法:
构建regular expression输入字符串,并将所有出现的正则表达式替换为空。
正则表达式将采用以下形式:
(a|b|c)\\b
(a|b|c)
匹配a
,b
或c
\\b
是一个单词边界,表示单词的结尾。
代码:
String[] arr = {"ical", "ic", "ion", "ogy"};
String input = "Hello world, this sentence is magic. Because we will talk about Biology.";
String regex = "(" + arr[0];
for (String s: arr)
regex += "|" + s; // using Pattern.quote(s) instead of s here would be safer
regex += ")\\b";
input = input.replaceAll(regex, "");
System.out.println(input);
打印:
Hello world, this sentence is mag. Because we will talk about Biol.
更复杂的方法:
构建trie个后缀,但反向。
从后面处理字符串。
如果你得到一个单词的开头,请查看trie中的下一个字符,如果你在trie中找到匹配项,请将它们删除。
最后使用StringBuilder
和StringBuilder.reverse()
来有效地执行此操作。
示例:强>
假设:
ical, ic, ion, ogy
你的特里会看起来像:
.
/|\
y // \\ l
/n| |c\
. . . .
g| o| |i |a
. . X .
o| i| |c
X X .
|i
X
(X
是终止节点(后缀的结尾),.
是非终止节点)
输入:
John Biology.
反向处理......
流程:"."
不是一个字,只需添加到输出。
输出= "."
流程:"Biology"
root有一个y
子节点,所以我们移动到那个节点
该节点有一个g
孩子,所以我们继续前进
该节点有一个o
子节点,所以我们继续前进。
然后我们到达了一个终止节点,因此丢弃已处理的字符并打印出其余的单词。
输出:".loiB"
流程:" "
不是一个字,只需添加到输出。
输出= ".loiB "
流程:"John"
root有一个n
子节点,所以我们移动到那个节点
该节点没有h
子节点,因此我们停止并输出处理后的字符以及单词的其余部分(即输出整个单词)。
输出= ".loiB nhoJ"
反向,给我们:"John Biol."
答案 1 :(得分:1)
我不知道这是否比循环更有效(我怀疑它是),但为什么不使用带有replaceAll()的正则表达式去除它们结尾的单词。
\ b标签确保只捕获单词结尾。
public class TestRegEx {
public static final String SENTENCE = "Hello world, this sentence is magic. Because we will talk about Biology. Physical. Reunion.";
public static final String PATTERN = "(ic|ogy|ical|ion)\\b";
public static void main(String[] args) {
System.out.println(SENTENCE.replaceAll(PATTERN, ""));
}
}
我得到的输出是:
你好世界,这句话是mag。因为我们会谈论Biol。物理学。 Reun。
希望有所帮助。
答案 2 :(得分:0)
如果您要检查的结尾数量有限,则可以为每个结尾生成正则表达式。这应该允许有效的检查,如果结束发生,你不需要拆分句子,并可以在一行中进行替换。
可悲的是,我的java正则表达式知识不够好,我可以动态构建所需的正则表达式,但你可以看看。但是有很多good tutorials out there。