/*
* Copyright (C) 2008-2015 by Holger Arndt
*
* This file is part of the Universal Java Matrix Package (UJMP).
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* UJMP is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* UJMP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with UJMP; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package org.ujmp.core.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.ujmp.core.Matrix;
import org.ujmp.core.collections.list.FastArrayList;
import org.ujmp.core.doublematrix.DenseDoubleMatrix2D;
import org.ujmp.core.doublematrix.impl.DefaultSparseDoubleMatrix;
import org.ujmp.core.util.VerifyUtil;
public abstract class TextUtil {
public static final String ALPHA_NUMERIC_REGEX = "^[A-Za-z0-9]+$";
public static final String HAS_DASH_REGEX = "^.+-.+$";
public static final String INIT_DASH_REGEX = "^-.+$";
public static final String END_DASH_REGEX = "^-.+$";
public static final String PUNCTUATION_REGEX = "^[,.:;!?]$";
public static final String ONE_QUESTION_MARK_REGEX = "^[?]$";
public static final String TWO_QUESTION_MARKS_REGEX = "^[??]$";
public static final String THREE_QUESTION_MARKS_REGEX = "^[???]$";
public static final String MULTIPLE_QUESTION_MARKS_REGEX = "^[?][?]+$";
public static final String ONE_EXCLAMATION_MARK_REGEX = "^[!]$";
public static final String TWO_EXCLAMATION_MARKS_REGEX = "^[!!]$";
public static final String THREE_EXCLAMATION_MARKS_REGEX = "^[!!!]$";
public static final String MULTIPLE_EXCLAMATION_MARKS_REGEX = "^[!][!]+$";
public static final String QUESTION_EXCLAMATION_MARK_REGEX = "^[?][!]$";
public static final String EXCLAMATION_QUESTION_MARK_REGEX = "^[!][?]$";
public static final String INIT_CAPS_REGEX = "^[A-Z].+$";
public static final String INIT_CAPS_ALPHA_REGEX = "^[A-Z][a-z]+$";
public static final String ONE_CAP_REGEX = "^[A-Z]$";
public static final String TWO_CAPS_REGEX = "^[A-Z][A-Z]$";
public static final String THREE_CAPS_REGEX = "^[A-Z][A-Z][A-Z]$";
public static final String FOUR_CAPS_REGEX = "^[A-Z][A-Z][A-Z][A-Z]$";
public static final String ALL_CAPS_REGEX = "^[A-Z]+$";
public static final String CAPS_MIX_REGEX = "^[A-Za-z]+$";
public static final String ONE_DIGIT_REGEX = "^[0-9]$";
public static final String TWO_DIGITS_REGEX = "^[0-9][0-9]$";
public static final String THREE_DIGITS_REGEX = "^[0-9][0-9][0-9]$";
public static final String FOUR_DIGITS_REGEX = "^[0-9][0-9][0-9][0-9]$";
public static final String HAS_DIGIT_REGEX = "^.+[0-9].+$";
public static final String POSITIVE_INTEGER_REGEX = "^[0-9]+$";
public static final String NEGATIVE_INTEGER_REGEX = "^-[0-9]+$";
public static final String FLOATING_POINT_NUMBER_REGEX = "^[-+]?[0-9]*\\.?[0-9]+$";
public static final String EXP_NUMBER_REGEX = "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$";
public static final String ROMAN_NUMBER_SMALL_REGEX = "^[ivxdlcm]+$";
public static final String ROMAN_NUMBER_CAPITAL_REGEX = "^[IVXDLCM]+$";
public static final String SINGLE_INITIAL_REGEX = "^[a-zA-Z]\\.$";
public static final String IN_PARENTHESES_REGEX = "^(.+)$";
public static final String OBD_REGEX = "^[PBCU][0-9A-F][0-9A-F][0-9A-F][0-9A-F]$";
public static final String YEAR_REGEX = "^[12][0-9][0-9][0-9]$";
public static final String HEX_REGEX = "^[0-9A-Fa-f][0-9A-Fa-f]+$";
public static final String EMAIL_REGEX = "^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$";
public static final String IP_REGEX = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
public static final String HTML_REGEX = "^<([a-z]+)([^<]+)*(?:>(.*)<\\/\\1>|\\s+\\/>)$";
public static final String URL_REGEX = "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$";
public static final DenseDoubleMatrix2D getCharacterFrequencies(final String s,
char... validCharacters) {
final String copy = s.toLowerCase();
final boolean[] isValidCharacter = createCharacterVector(validCharacters);
final double[] freq = new double[256];
for (int i = copy.length(); --i != -1;) {
final char c = copy.charAt(i);
if (c < 256 && isValidCharacter[c]) {
freq[c]++;
}
}
return Matrix.Factory.linkToArray(freq);
}
public static final List splitLineIntoSentences(final String line) {
VerifyUtil.verifyNotNull(line, "text cannot be null");
VerifyUtil.verifyTrue(line.split("\n").length == 1, "text must be in one line");
StringTokenizer tokenizer = new StringTokenizer(line, ".:;!?", true);
final List tokens = new FastArrayList();
String token1 = null;
String token2 = null;
String token3 = null;
while (tokenizer.hasMoreTokens()) {
token1 = token2;
token2 = token3;
token3 = tokenizer.nextToken();
if (token2 != null && token2.trim().isEmpty()) {
continue;
}
if (token1 != null && token2 != null && token3 != null) {
if (".".equals(token2)) {
if (tokens.isEmpty()) {
tokens.add(token1 + token2);
} else {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token2);
}
} else if (":".equals(token2)) {
if (tokens.isEmpty()) {
tokens.add(token1 + token2);
} else {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token2);
}
} else if (";".equals(token2)) {
if (tokens.isEmpty()) {
tokens.add(token1 + token2);
} else {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token2);
}
} else if ("!".equals(token2)) {
if (tokens.isEmpty()) {
tokens.add(token1 + token2);
} else {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token2);
}
} else if ("?".equals(token2)) {
if (tokens.isEmpty()) {
tokens.add(token1 + token2);
} else {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token2);
}
} else if (tokens.isEmpty()) {
tokens.add(token2);
} else if (endsWithAbbreviation(tokens.get(tokens.size() - 1))) {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token2);
} else {
tokens.add(token2);
}
}
}
if (token1 != null && token2 != null && token3 != null) {
if (".".equals(token3)) {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token3);
} else if (":".equals(token3)) {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token3);
} else if (";".equals(token3)) {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token3);
} else if ("?".equals(token3)) {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token3);
} else if ("!".equals(token3)) {
tokens.set(tokens.size() - 1, tokens.get(tokens.size() - 1) + token3);
}
} else if (token1 != null && token2 != null && token3 == null) {
// handle short sentences
tokens.add(token1);
tokens.add(token2);
} else if (token1 != null && token2 == null && token3 == null) {
// only one token
tokens.add(token1);
}
return tokens;
}
public static final DefaultTextBlock splitTextIntoObjects(String text) {
DefaultTextBlock textBlock = new DefaultTextBlock();
text = text.replaceAll("\r\n", " ").replaceAll("\n", " ");
List sentenceTexts = splitLineIntoSentences(text);
int s = 0;
for (String sentenceText : sentenceTexts) {
TextSentence sentence = new DefaultTextSentence();
sentence.setMetaData("Id", s++);
List tokenTexts = splitSentenceIntoTokens(sentenceText, 0);
int i = 0;
for (String tokenText : tokenTexts) {
TextToken token = new DefaultTextToken(tokenText);
token.put("Id", i++);
sentence.add(token);
}
textBlock.add(sentence);
}
return textBlock;
}
public static final List> createWordTrigrams(String text) {
List> wordTrigrams = new FastArrayList>();
List lines = splitTextIntoLines(text);
for (String line : lines) {
List sentences = splitLineIntoSentences(line);
for (String sentence : sentences) {
wordTrigrams.addAll(createWordTrigrams(splitSentenceIntoTokens(sentence, 3)));
}
}
return wordTrigrams;
}
public static final List splitTextIntoLines(String text) {
VerifyUtil.verifyNotNull(text, "text cannot be null");
return Arrays.asList(text.split("\n"));
}
public static final List> createWordBigrams(String text) {
List> wordBigrams = new FastArrayList>();
List lines = splitTextIntoLines(text);
for (String line : lines) {
List sentences = splitLineIntoSentences(line);
for (String sentence : sentences) {
wordBigrams.addAll(createWordBigrams(splitSentenceIntoTokens(sentence, 2)));
}
}
return wordBigrams;
}
public static final List createWordUnigrams(String text, int ngramSize) {
List wordUnigrams = new FastArrayList();
List lines = splitTextIntoLines(text);
for (String line : lines) {
List sentences = splitLineIntoSentences(line);
for (String sentence : sentences) {
wordUnigrams.addAll(splitSentenceIntoTokens(sentence, ngramSize));
}
}
return wordUnigrams;
}
public static Map, Integer> getWordBigramCounts(String text) {
List> wordBigrams = createWordBigrams(text);
Map, Integer> wordBigramCounts = new HashMap, Integer>();
for (List wordBigram : wordBigrams) {
Integer count = wordBigramCounts.get(wordBigram);
count = count == null ? 1 : count + 1;
wordBigramCounts.put(wordBigram, count);
}
return wordBigramCounts;
}
public static Map getWordUnigramCounts(String text, int ngramSize) {
List wordUnigrams = createWordUnigrams(text, ngramSize);
Map wordUnigramCounts = new HashMap();
for (String wordUnigram : wordUnigrams) {
Integer count = wordUnigramCounts.get(wordUnigram);
count = count == null ? 1 : count + 1;
wordUnigramCounts.put(wordUnigram, count);
}
return wordUnigramCounts;
}
public static final List splitSentenceIntoTokens(final String sentence, int ngramSize) {
VerifyUtil.verifyNotNull(sentence, "text cannot be null");
VerifyUtil.verifyTrue(sentence.split("\n").length == 1, "text must be in one line");
sentence.replace((char) 160, ' ');
StringTokenizer tokenizer = new StringTokenizer(sentence,
" \u00A0.;,ãÂÂÃÂ:&\\âÂÂ/âÂÂâÂÂâÂÂ\"âÂÂâÂÂâÂÂâÂÂâÂÂ-!?{}()[]", true);
final List tokens = new FastArrayList();
for (int i = 1; i < ngramSize; i++) {
tokens.add("".intern());
}
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken().trim();
if (!token.isEmpty() && !token.equals("\u00A0")) {
tokens.add(token.intern());
}
}
for (int i = 1; i < ngramSize; i++) {
tokens.add("".intern());
}
return tokens;
}
public static final List> createWordBigrams(List words) {
List> wordBigrams = new FastArrayList>();
for (int i = 0; i < words.size() - 1; i++) {
String word1 = words.get(i);
String word2 = words.get(i + 1);
List bigram = new FastArrayList(2);
bigram.add(word1);
bigram.add(word2);
wordBigrams.add(bigram);
}
return wordBigrams;
}
public static final List> createWordTrigrams(List words) {
List> wordTrigrams = new FastArrayList>();
for (int i = 0; i < words.size() - 2; i++) {
String word1 = words.get(i);
String word2 = words.get(i + 1);
String word3 = words.get(i + 2);
List trigram = new FastArrayList(3);
trigram.add(word1);
trigram.add(word2);
trigram.add(word3);
wordTrigrams.add(trigram);
}
return wordTrigrams;
}
public static boolean endsWithAbbreviation(String string) {
string = string.toLowerCase();
if (string.endsWith(" 0.")) {
return true;
} else if (string.endsWith(" 1.")) {
return true;
} else if (string.endsWith(" 2.")) {
return true;
} else if (string.endsWith(" 3.")) {
return true;
} else if (string.endsWith(" 4.")) {
return true;
} else if (string.endsWith(" 5.")) {
return true;
} else if (string.endsWith(" 6.")) {
return true;
} else if (string.endsWith(" 7.")) {
return true;
} else if (string.endsWith(" 8.")) {
return true;
} else if (string.endsWith(" 9.")) {
return true;
} else if (string.endsWith("10.")) {
return true;
} else if (string.endsWith("11.")) {
return true;
} else if (string.endsWith("12.")) {
return true;
} else if (string.endsWith("13.")) {
return true;
} else if (string.endsWith("14.")) {
return true;
} else if (string.endsWith("15.")) {
return true;
} else if (string.endsWith("16.")) {
return true;
} else if (string.endsWith("17.")) {
return true;
} else if (string.endsWith("18.")) {
return true;
} else if (string.endsWith("19.")) {
return true;
} else if (string.endsWith("20.")) {
return true;
} else if (string.endsWith("21.")) {
return true;
} else if (string.endsWith("22.")) {
return true;
} else if (string.endsWith("23.")) {
return true;
} else if (string.endsWith("24.")) {
return true;
} else if (string.endsWith("25.")) {
return true;
} else if (string.endsWith("26.")) {
return true;
} else if (string.endsWith("27.")) {
return true;
} else if (string.endsWith("28.")) {
return true;
} else if (string.endsWith("29.")) {
return true;
} else if (string.endsWith("30.")) {
return true;
} else if (string.endsWith("31.")) {
return true;
} else if (string.endsWith("32.")) {
return true;
} else if (string.endsWith("33.")) {
return true;
} else if (string.endsWith("34.")) {
return true;
} else if (string.endsWith("35.")) {
return true;
} else if (string.endsWith("36.")) {
return true;
} else if (string.endsWith("37.")) {
return true;
} else if (string.endsWith("38.")) {
return true;
} else if (string.endsWith("39.")) {
return true;
} else if (string.endsWith(" 0:")) {
return true;
} else if (string.endsWith(" 1:")) {
return true;
} else if (string.endsWith(" 2:")) {
return true;
} else if (string.endsWith(" 3:")) {
return true;
} else if (string.endsWith(" 4:")) {
return true;
} else if (string.endsWith(" 5:")) {
return true;
} else if (string.endsWith(" 6:")) {
return true;
} else if (string.endsWith(" 7:")) {
return true;
} else if (string.endsWith(" 8:")) {
return true;
} else if (string.endsWith(" 9:")) {
return true;
} else if (string.endsWith(" a.")) {
return true;
} else if (string.endsWith(" b.")) {
return true;
} else if (string.endsWith(" c.")) {
return true;
} else if (string.endsWith(" d.")) {
return true;
} else if (string.endsWith(" e.")) {
return true;
} else if (string.endsWith(" f.")) {
return true;
} else if (string.endsWith(" g.")) {
return true;
} else if (string.endsWith(" h.")) {
return true;
} else if (string.endsWith(" i.")) {
return true;
} else if (string.endsWith(" j.")) {
return true;
} else if (string.endsWith(" k.")) {
return true;
} else if (string.endsWith(" l.")) {
return true;
} else if (string.endsWith(" m.")) {
return true;
} else if (string.endsWith(" n.")) {
return true;
} else if (string.endsWith(" o.")) {
return true;
} else if (string.endsWith(" p.")) {
return true;
} else if (string.endsWith(" q.")) {
return true;
} else if (string.endsWith(" r.")) {
return true;
} else if (string.endsWith(" s.")) {
return true;
} else if (string.endsWith(" t.")) {
return true;
} else if (string.endsWith(" u.")) {
return true;
} else if (string.endsWith(" v.")) {
return true;
} else if (string.endsWith(" w.")) {
return true;
} else if (string.endsWith(" x.")) {
return true;
} else if (string.endsWith(" y.")) {
return true;
} else if (string.endsWith(" z.")) {
return true;
} else if (string.endsWith(" ä.")) {
return true;
} else if (string.endsWith(" ö.")) {
return true;
} else if (string.endsWith(" ü.")) {
return true;
} else if (string.endsWith(" ÃÂ.")) {
return true;
} else if (string.endsWith(".a.")) {
return true;
} else if (string.endsWith(".b.")) {
return true;
} else if (string.endsWith(".c.")) {
return true;
} else if (string.endsWith(".d.")) {
return true;
} else if (string.endsWith(".e.")) {
return true;
} else if (string.endsWith(".f.")) {
return true;
} else if (string.endsWith(".g.")) {
return true;
} else if (string.endsWith(".h.")) {
return true;
} else if (string.endsWith(".i.")) {
return true;
} else if (string.endsWith(".j.")) {
return true;
} else if (string.endsWith(".k.")) {
return true;
} else if (string.endsWith(".l.")) {
return true;
} else if (string.endsWith(".m.")) {
return true;
} else if (string.endsWith(".n.")) {
return true;
} else if (string.endsWith(".o.")) {
return true;
} else if (string.endsWith(".p.")) {
return true;
} else if (string.endsWith(".q.")) {
return true;
} else if (string.endsWith(".r.")) {
return true;
} else if (string.endsWith(".s.")) {
return true;
} else if (string.endsWith(".t.")) {
return true;
} else if (string.endsWith(".u.")) {
return true;
} else if (string.endsWith(".v.")) {
return true;
} else if (string.endsWith(".w.")) {
return true;
} else if (string.endsWith(".x.")) {
return true;
} else if (string.endsWith(".y.")) {
return true;
} else if (string.endsWith(".z.")) {
return true;
} else if (string.endsWith(".ä.")) {
return true;
} else if (string.endsWith(".ö.")) {
return true;
} else if (string.endsWith(".ü.")) {
return true;
} else if (string.endsWith(".ÃÂ.")) {
return true;
} else if (string.endsWith(" ca.")) {
return true;
} else if (string.endsWith(" vs.")) {
return true;
} else if (string.endsWith(" rep.")) {
return true;
} else if (string.endsWith(" etc.")) {
return true;
} else if (string.endsWith(" usw.")) {
return true;
} else if (string.endsWith(" resp.")) {
return true;
} else if (string.endsWith(" incl.")) {
return true;
} else if (string.endsWith(" inkl.")) {
return true;
} else if (string.endsWith(" insges.")) {
return true;
} else if (string.endsWith(" zyl.")) {
return true;
} else if (string.endsWith(" cyl.")) {
return true;
} else if (string.endsWith(" dr.")) {
return true;
} else if (string.endsWith(" prof.")) {
return true;
} else if (string.endsWith(" gr.")) {
return true;
} else if (string.endsWith(" ppm.")) {
return true;
} else if (string.endsWith(" ggf.")) {
return true;
} else
return false;
}
private static final boolean[] createCharacterVector(char... chars) {
final boolean[] characterVector = new boolean[256];
if (chars.length == 0) {
Arrays.fill(characterVector, true);
} else {
for (char c : chars) {
if (c < 256) {
characterVector[c] = true;
}
}
}
return characterVector;
}
public static final Matrix getCharacterBigramFrequencies(final String s,
char... validCharacters) {
final String copy = " " + s.toLowerCase() + " ";
final boolean[] isValidCharacter = createCharacterVector(validCharacters);
final Matrix m = new DefaultSparseDoubleMatrix(65536, 1);
for (int i = copy.length(); --i != 0;) {
final char c1 = copy.charAt(i - 1);
final char c2 = copy.charAt(i);
if (c1 < 256 && c2 < 256 && isValidCharacter[c1] && isValidCharacter[c2]) {
final int index = c1 * 256 + c2;
m.setAsDouble(m.getAsDouble(index, 0) + 1, index, 0);
}
}
return m;
}
public static final Matrix getCharacterTrigramFrequencies(final String s,
char... validCharacters) {
final String copy = " " + s.toLowerCase() + " ";
final boolean[] isValidCharacter = createCharacterVector(validCharacters);
final Matrix m = new DefaultSparseDoubleMatrix(16777216, 1);
for (int i = copy.length(); --i != 0;) {
final char c1 = copy.charAt(i - 2);
final char c2 = copy.charAt(i - 1);
final char c3 = copy.charAt(i);
if (c1 < 256 && c2 < 256 && c3 < 256 && isValidCharacter[c1] && isValidCharacter[c2]
&& isValidCharacter[c3]) {
final int index = c1 * 65536 + c2 * 256 + c3;
m.setAsDouble(m.getAsDouble(index, 0) + 1, index, 0);
}
}
return m;
}
public static final Matrix createBagOfWordsVector(String string, List dictionary) {
Matrix m = Matrix.Factory.zeros(dictionary.size(), 1);
StringTokenizer st = new StringTokenizer(string, " \t\n\r\f,.:;?![]'");
while (st.hasMoreElements()) {
long index = dictionary.indexOf(st.nextElement());
m.setAsDouble(m.getAsDouble(index, 0) + 1, index, 0);
}
return m;
}
public static Collection convertSentenceToTextTokens(String sentence) {
List strings = TextUtil.splitSentenceIntoTokens(sentence, 1);
List tokens = new ArrayList();
for (String string : strings) {
TextToken textToken = new DefaultTextToken(string);
tokens.add(textToken);
}
return tokens;
}
public static Collection convertToTextBlockToSentences(String text) {
List strings = TextUtil.splitTextIntoSentences(text);
List sentences = new ArrayList();
for (String string : strings) {
TextSentence textToken = new DefaultTextSentence(string);
sentences.add(textToken);
}
return sentences;
}
public static List splitTextIntoSentences(String text) {
text = text.replaceAll("\n", " ");
return splitLineIntoSentences(text);
}
public static Matrix stringToVector(String string) {
return stringToVector(string, 131072);
}
public static Matrix stringToVector(String string, int size) {
Matrix m = Matrix.Factory.zeros(size, 1);
StringTokenizer st = new StringTokenizer(string, " \t\n\r\f,.:;?![]'");
while (st.hasMoreElements()) {
long index = Math.abs(st.nextElement().toString().toLowerCase().hashCode()) % size;
m.setAsDouble(m.getAsDouble(index, 0) + 1, index, 0);
}
return m;
}
}
Ads help maintain this website.