Simple Stringsearch is a simple API for searching for multiple strings within a stream of characters. It works by building a finite state automata based on the searchterms. The finite state automata can be saved to avoid having to rebuild it for every search.
This API requires Java 5.0 or later
The latest version of the API can be downloaded here , the distribution contains full sourcecode along with jar and documentation. There is also a maven repository at http://sstringsearch.sourceforge.org/maven/repo/ .
The Javadocs can be found here .
This is an example of how to use SimpleStringsearch for both search and search&replace.
To add a searchterm, we simply call StringSearch.addSearchTerm() This method takes two parameters, the searchterm itself and a HitListener object. This object will be associated with the searchterm and the HitListener.foundAt() method will be invoked whenever the searchterm is encountered during search. Notice that HitListener.foundAt() returns true . This will force the search to continue after a hit is found. If you return false, search will halt upon a hit. Example:
import java.io.IOException; import java.io.StringReader; import org.kriand.sstringsearch.StringSearchFactory; import org.kriand.sstringsearch.search.Searcher; import org.kriand.sstringsearch.search.SearchingHitListener; public class ExampleSearch { public static void main(String[] args) { try{ Searcher s = StringSearchFactory.getSearcher(); ExampleHitListener listener = new ExampleHitListener(); s.addSearchTerm("abc", listener); s.addSearchTerm("fgh", listener); s.search(new StringReader("abcdefgh")); System.out.println("Count is: " + listener.getCount()); } catch(IOException ex){ ex.printStackTrace(); } } } class ExampleHitListener implements SearchingHitListener{ private int count; public ExampleHitListener(){ count = 0; } public boolean foundAt(long startIndex, long endIndex, String term, Object... callbackArgs) { count++; return true; } public int getCount(){ return count; } }
Output is Count is: 2
To perform search&replace, we call StringSearch.addSearchTerm() with the searchterm itself and a ReplacingHitListener object. This object will be associated with the searchterm and the ReplacingHitListener.replace() method will be invoked whenever the searchterm is encountered. The String returned from ReplacingHitListener.replace() will replace the original String in the result. Here is an example that reverses all occurrences of the strings "abc" and "123":
import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import org.kriand.sstringsearch.StringSearchFactory; import org.kriand.sstringsearch.replace.Replacer; import org.kriand.sstringsearch.replace.ReplacingHitListener; public class ExampleSearchAndReplace { public static void main(String[] args) { try{ Replacer r = StringSearchFactory.getReplacer(); StringWriter result = new StringWriter(); ExampleReplacingHitListener listener = new ExampleReplacingHitListener(); r.addSearchTerm("abc", listener); r.addSearchTerm("123", listener); r.searchAndReplace(new StringReader("Test1: abc. Test2: 123"), result); System.out.println(result.toString()); } catch(IOException ex){ ex.printStackTrace(); } } } class ExampleReplacingHitListener implements ReplacingHitListener{ public String replace(String stringToReplace, Object... callbackArguments) { return (new StringBuilder(stringToReplace)).reverse().toString(); } }
Output is Test1: cba. Test2: 321
It is also possible to perform a search across multiple input sources. Example:
import java.io.IOException; import java.io.StringReader; import org.kriand.sstringsearch.State; import org.kriand.sstringsearch.StringSearchFactory; import org.kriand.sstringsearch.search.Searcher; import org.kriand.sstringsearch.search.SearchingHitListener; public class ExampleSearch { public static void main(String[] args) { try { Searcher s = StringSearchFactory.getSearcher(); ExampleHitListener listener = new ExampleHitListener(); s.addSearchTerm("abc", listener); s.addSearchTerm("fgh", listener); State state = s.search(new StringReader("ab")); state = s.search(new StringReader("cd"), state); state = s.search(new StringReader("ef"), state); state = s.search(new StringReader("gh"), state); state = s.search(new StringReader("ij"), state); System.out.println("Count is: " + listener.getCount()); } catch (IOException ex) { ex.printStackTrace(); } } } class ExampleHitListener implements SearchingHitListener { private int count; public ExampleHitListener() { count = 0; } public boolean foundAt(long startIndex, long endIndex, String term, Object... callbackArgs) { count++; return true; } public int getCount() { return count; } }
Output is Count is: 2
When you have added all the searchterms, you might want to save it to avoid rebuilding it before every search. The StringSearch class contains utilitymethods to easily save and load the finite state automata to and from a file or other resource. To save the finite state automata you have to make sure your listeners, and all classes they depend on, are serializable. A saved finite state automata can be easily loaded with the static StringSearchFactory.load() methods.