Considere las siguientes dos cadenas:
1. for (int i = 0; i < b.size(); i++) {
2. do something in English (not necessary to be a sentence).
El primero es código Java, el segundo es inglés. ¿Cómo detectar que el primero es código y el segundo es inglés?
Es posible que el código Java no se pueda analizar porque no es un método / declaración / expresión completa. Lo siguiente proporciona una solución para este problema. Como a veces, no hay una línea clara entre el código y el inglés, la precisión no puede ser del 100%. Sin embargo, con la siguiente solución, puede ajustar fácilmente el programa para que se adapte a sus necesidades. Puede descargar el código desde GitHub.
La idea básica es convertir la cadena en un conjunto de tokens. Por ejemplo, la línea de código anterior puede convertirse en «CLAVE, SEPARADOR, ID, ASIGNACIÓN, NÚMERO, SEPARADOR, …». Y luego podemos usar reglas simples para separar el código del inglés.
Una clase de tokenizador convierte una cadena en una lista de tokens.
package lexical;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Tokenizer {
private class TokenInfo {
public final Pattern regex;
public final int token;
public TokenInfo(Pattern regex, int token) {
super();
this.regex = regex;
this.token = token;
}
}
public class Token {
public final int token;
public final String sequence;
public Token(int token, String sequence) {
super();
this.token = token;
this.sequence = sequence;
}
}
private LinkedList<TokenInfo> tokenInfos;
private LinkedList<Token> tokens;
public Tokenizer() {
tokenInfos = new LinkedList<TokenInfo>();
tokens = new LinkedList<Token>();
}
public void add(String regex, int token) {
tokenInfos
.add(new TokenInfo(Pattern.compile("^(" + regex + ")"), token));
}
public void tokenize(String str) {
String s = str.trim();
tokens.clear();
while (!s.equals("")) {
//System.out.println(s);
boolean match = false;
for (TokenInfo info : tokenInfos) {
Matcher m = info.regex.matcher(s);
if (m.find()) {
match = true;
String tok = m.group().trim();
s = m.replaceFirst("").trim();
tokens.add(new Token(info.token, tok));
break;
}
}
if (!match){
//throw new ParserException("Unexpected character in input: " + s);
tokens.clear();
System.out.println("Unexpected character in input: " + s);
return;
}
}
}
public LinkedList<Token> getTokens() {
return tokens;
}
public String getTokensString() {
StringBuilder sb = new StringBuilder();
for (Tokenizer.Token tok : tokens) {
sb.append(tok.token);
}
return sb.toString();
}
}
|
paquete léxico; import java.util.LinkedList; import java.util.regex.Matcher; import java.util.regex.Pattern; Tokenizer de clase pública {TokenInfo de clase privada {regex de patrón final público; token int final público; TokenInfo público (patrón regex, int token) {super (); this.regex = regex; this.token = token; }} token de clase pública {token int final público; secuencia de cadena final pública; Token público (token int, secuencia de cadenas) {super (); this.token = token; this.sequence = secuencia; }} private LinkedList tokenInfos; tokens privados LinkedList ; Tokenizer público () {tokenInfos = new LinkedList (); tokens = new LinkedList (); } public void add (String regex, int token) {tokenInfos .add (new TokenInfo (Pattern.compile («^ (» + regex + «)»), token)); } tokenize public void (String str) {String s = str.trim (); tokens.clear (); while (! s.equals («»)) {//System.out.println(s); coincidencia booleana = falso; para (TokenInfo info: tokenInfos) {Matcher m = info.regex.matcher (s); if (m.find ()) {coincidencia = verdadero; Cadena tok = m.group (). Trim (); s = m.replaceFirst («»). trim (); tokens.add (nuevo Token (info.token, tok)); descanso; }} if (! match) {// lanza una nueva ParserException («Carácter inesperado en la entrada:» + s); tokens.clear (); System.out.println («Carácter inesperado en la entrada:» + s); regreso; }}} public LinkedList getTokens () {tokens de retorno; } public String getTokensString () {StringBuilder sb = new StringBuilder (); para (Tokenizer.Token tok: tokens) {sb.append (tok.token); } return sb.toString (); }}
Podemos obtener las palabras clave, separadores, operadores, identificadores de Java, etc. Si asignamos un valor de mapeo a los tokens, una cadena de inglés se puede convertir en una cadena de tokens.
package lexical;
import greenblocks.javaapiexamples.DB;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import NLP.POSTagger;
public class EnglishOrCode {
private static Tokenizer tokenizer = null;
public static void initializeTokenizer() {
tokenizer = new Tokenizer();
//key words
String keyString = "abstract assert boolean break byte case catch "
+ "char class const continue default do double else enum"
+ " extends false final finally float for goto if implements "
+ "import instanceof int interface long native new null "
+ "package private protected public return short static "
+ "strictfp super switch synchronized this throw throws true "
+ "transient try void volatile while todo";
String[] keys = keyString.split(" ");
String keyStr = StringUtils.join(keys, "|");
tokenizer.add(keyStr, 1);
tokenizer.add("(|)|{|}|[|]|;|,|.|=|>|<|!|~|"
+ "?|:|==|<=|>=|!=|&&||||++|--|"
+ "+|-|*|/|&|||^|%|'|"|n|r|$|#",
2);//separators, operators, etc
tokenizer.add("[0-9]+", 3); //number
tokenizer.add("[a-zA-Z][a-zA-Z0-9_]*", 4);//identifier
tokenizer.add("@", 4);
}
public static void main(String[] args) throws SQLException, ClassNotFoundException, IOException {
initializeTokenizer();
String s = "do something in English";
if(isEnglish(s)){
System.out.println("English");
}else{
System.out.println("Java Code");
}
s = "for (int i = 0; i < b.size(); i++) {";
if(isEnglish(s)){
System.out.println("English");
}else{
System.out.println("Java Code");
}
}
private static boolean isEnglish(String replaced) {
tokenizer.tokenize(replaced);
String patternString = tokenizer.getTokensString();
if(patternString.matches(".*444.*") || patternString.matches("4+")){
return true;
}else{
return false;
}
}
}
|
paquete léxico; importar greenblocks.javaapiexamples.DB; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import NLP.POSTagger; public class EnglishOrCode {tokenizador de tokenizador estático privado = nulo; public static void initializeTokenizer () {tokenizer = new Tokenizer (); // palabras clave String keyString = «resumen aserción booleana break byte case catch» + «char class const continue default do double else enum» + «extiende false final finalmente float for goto if implementa» + «import instanceof int interface long native new null «+» paquete privado protegido público retorno corto estático «+» estrictofp super interruptor sincronizado este lanzamiento arroja verdadero «+» intento transitorio void volatile while todo «; Cuerda[] keys = keyString.split («»); String keyStr = StringUtils.join (claves, «|»); tokenizer.add (keyStr, 1); tokenizer.add (» (| ) | {| } | [|]|; |, | . | = |> | <|! | ~ | "+" ? |: | == | <= |> = |! = | && | | || + + | – | «+» + | – | * | / | & | || ^ |% | ‘| «| n | r | $ | # «, 2); // separadores, operadores, etc. tokenizer.add («[0-9]+ «, 3); // tokenizador de números.add («[a-zA-Z][a-zA-Z0-9_]* «, 4); // identificador tokenizer.add (» @ «, 4);} public static void main (String[] args) lanza SQLException, ClassNotFoundException, IOException {initializeTokenizer (); String s = «hacer algo en inglés»; if (isEnglish (s)) {System.out.println («Inglés»); } else {System.out.println («Código Java»); } s = «para (int i = 0; i
Producción:
English
Java Code
Referencias:
1. Escribir un analizador en Java: el Tokenizer