More precise keyword replacement: does not highlight 'fo' in "for".

cefexperiments 5323
Danny van Heumen 11 years ago
parent 0f2b7f4507
commit 3c8b3127ad

@ -20,6 +20,21 @@
public class KeywordReplacer
implements Replacer
{
/**
* Index of the optional prefix group in the regex.
*/
private static final int INDEX_OPTIONAL_PREFIX_GROUP = 1;
/**
* Index of the keyword match group in the regex.
*/
private static final int INDEX_KEYWORD_MATCH_GROUP = 2;
/**
* Index of the optional suffix group in the regex.
*/
private static final int INDEX_OPTIONAL_SUFFIX_GROUP = 3;
/**
* The keyword to highlight.
*/
@ -65,15 +80,17 @@ public void replace(final StringBuilder target, final String piece)
}
final Matcher m =
Pattern.compile(Pattern.quote(keyword), Pattern.CASE_INSENSITIVE)
.matcher(piece);
Pattern.compile("(^|\\W)(" + Pattern.quote(keyword) + ")(\\W|$)",
Pattern.CASE_INSENSITIVE).matcher(piece);
int prevEnd = 0;
while (m.find())
{
target.append(StringEscapeUtils.escapeHtml4(piece.substring(
prevEnd, m.start())));
prevEnd = m.end();
final String keywordMatch = m.group().trim();
prevEnd, m.start()
+ m.group(INDEX_OPTIONAL_PREFIX_GROUP).length())));
prevEnd = m.end() - m.group(INDEX_OPTIONAL_SUFFIX_GROUP).length();
final String keywordMatch =
m.group(INDEX_KEYWORD_MATCH_GROUP).trim();
target.append("<b>");
target.append(StringEscapeUtils.escapeHtml4(keywordMatch));
target.append("</b>");

@ -0,0 +1,143 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.chat.replacers;
import junit.framework.*;
/**
* Tests for keyword replacer.
*
* @author Danny van Heumen
*/
public class KeywordReplacerTest
extends TestCase
{
public void testConstructWithoutKeyword()
{
new KeywordReplacer(null);
}
public void testConstructEmptyKeyword()
{
new KeywordReplacer("");
}
public void testConstructWithKeyword()
{
new KeywordReplacer("keyword");
}
public void testExpectPlainText()
{
KeywordReplacer replacer = new KeywordReplacer("test");
Assert.assertTrue(replacer.expectsPlainText());
}
public void testNullKeywordReplacement()
{
KeywordReplacer replacer = new KeywordReplacer(null);
StringBuilder target = new StringBuilder();
replacer.replace(target, "this is a piece of text");
Assert.assertEquals("this is a piece of text", target.toString());
}
public void testEmptyKeywordReplacement()
{
KeywordReplacer replacer = new KeywordReplacer("");
StringBuilder target = new StringBuilder();
replacer.replace(target, "this is a piece of text");
Assert.assertEquals("this is a piece of text", target.toString());
}
public void testTrivialKeywordReplace()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "word");
Assert.assertEquals("<b>word</b>", target.toString());
}
public void testKeywordTooSmallForReplacement()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "wor");
Assert.assertEquals("wor", target.toString());
}
public void testKeywordInSentence()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "some word in a sentence");
Assert.assertEquals("some <b>word</b> in a sentence", target.toString());
}
public void testKeywordAtSentenceStart()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "word first in a sentence");
Assert.assertEquals("<b>word</b> first in a sentence", target.toString());
}
public void testKeywordAtSentenceEnd()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "last in a sentence word");
Assert.assertEquals("last in a sentence <b>word</b>", target.toString());
}
public void testKeywordInSentenceMultipleHits()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "1 word 2 word 3 word 4");
Assert.assertEquals("1 <b>word</b> 2 <b>word</b> 3 <b>word</b> 4", target.toString());
}
public void testDontReplaceKeywordInsideWord()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "A sentence containing keywords.");
Assert.assertEquals("A sentence containing keywords.", target.toString());
}
public void testDontReplaceKeywordHeadingWord()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "I am the wordsmith.");
Assert.assertEquals("I am the wordsmith.", target.toString());
}
public void testDontReplaceKeywordTrailingWord()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "Don't find the word in keyword.");
Assert.assertEquals("Don't find the <b>word</b> in keyword.", target.toString());
}
public void testReplaceKeywordAllowPunctuation()
{
KeywordReplacer replacer = new KeywordReplacer("word");
StringBuilder target = new StringBuilder();
replacer.replace(target, "Find the hidden word, word. (word) between parentheses.");
Assert.assertEquals("Find the hidden <b>word</b>, <b>word</b>. (<b>word</b>) between parentheses.", target.toString());
}
public void testReplaceKeywordAllowPunctuation2()
{
KeywordReplacer replacer = new KeywordReplacer("fo");
StringBuilder target = new StringBuilder();
replacer.replace(target, "fo: Whenever someone writes \"for\" or any other word that starts with \"fo\" it recognizes it as my nickname ...");
Assert.assertEquals("<b>fo</b>: Whenever someone writes &quot;for&quot; or any other word that starts with &quot;<b>fo</b>&quot; it recognizes it as my nickname ...", target.toString());
}
}
Loading…
Cancel
Save