使用 BufferedReader 翻译字符串中的单词 (Java)
Translate words in a string using BufferedReader (Java)
我已经为此工作了几天,但我无法取得任何进展。我试过使用 Scanner 和 BufferedReader 但没有成功。
基本上,我有一个工作方法 (shortenWord),它接受一个字符串并根据格式如下的文本文件缩短它:
hello,lo
any,ne
anyone,ne1
thanks,thx
它也考虑了标点符号,所以 'hello?' 变成了 'lo?' 等等
我需要能够读取字符串并单独翻译每个单词,因此 "hello? any anyone thanks!" 将变为 "lo? ne ne1 thx!",基本上使用我已经对字符串中的每个单词使用的方法。我拥有的代码将翻译第一个单词,但对其余单词不执行任何操作。我认为这与我的 BufferedReader 的工作方式有关。
import java.io.*;
public class Shortener {
private FileReader in ;
/*
* Default constructor that will load a default abbreviations text file.
*/
public Shortener() {
try {
in = new FileReader( "abbreviations.txt" );
}
catch ( Exception e ) {
System.out.println( e );
}
}
public String shortenWord( String inWord ) {
String punc = new String(",?.!;") ;
char finalchar = inWord.charAt(inWord.length()-1) ;
String outWord = new String() ;
BufferedReader abrv = new BufferedReader(in) ;
// ends in punctuation
if (punc.indexOf(finalchar) != -1 ) {
String sub = inWord.substring(0, inWord.length()-1) ;
outWord = sub + finalchar ;
try {
String line;
while ( (line = abrv.readLine()) != null ) {
String[] lineArray = line.split(",") ;
if ( line.contains(sub) ) {
outWord = lineArray[1] + finalchar ;
}
}
}
catch (IOException e) {
System.out.println(e) ;
}
}
// no punctuation
else {
outWord = inWord ;
try {
String line;
while( (line = abrv.readLine()) != null) {
String[] lineArray = line.split(",") ;
if ( line.contains(inWord) ) {
outWord = lineArray[1] ;
}
}
}
catch (IOException ioe) {
System.out.println(ioe) ;
}
}
return outWord;
}
public void shortenMessage( String inMessage ) {
String[] messageArray = inMessage.split("\s+") ;
for (String word : messageArray) {
System.out.println(shortenWord(word));
}
}
}
任何帮助,甚至是正确方向的推动,我们将不胜感激。
编辑:我试过在 shortenWord 方法的末尾关闭 BufferedReader,但它只是导致我在第一个表示 BufferedReader 已关闭的字词之后对字符串中的每个字词都出错。
我认为您可以使用 HashMap
获得更简单的解决方案。创建 Shortener
对象时将所有缩写读入地图,一旦有单词就引用它。单词将是 key
,缩写是 value
。像这样:
public class Shortener {
private FileReader in;
//the map
private HashMap<String, String> abbreviations;
/*
* Default constructor that will load a default abbreviations text file.
*/
public Shortener() {
//initialize the map
this.abbreviations = new HashMap<>();
try {
in = new FileReader("abbreviations.txt" );
BufferedReader abrv = new BufferedReader(in) ;
String line;
while ((line = abrv.readLine()) != null) {
String [] abv = line.split(",");
//If there is not two items in the file, the file is malformed
if (abv.length != 2) {
throw new IllegalArgumentException("Malformed abbreviation file");
}
//populate the map with the word as key and abbreviation as value
abbreviations.put(abv[0], abv[1]);
}
}
catch ( Exception e ) {
System.out.println( e );
}
}
public String shortenWord( String inWord ) {
String punc = new String(",?.!;") ;
char finalchar = inWord.charAt(inWord.length()-1) ;
// ends in punctuation
if (punc.indexOf(finalchar) != -1) {
String sub = inWord.substring(0, inWord.length() - 1);
//Reference map
String abv = abbreviations.get(sub);
if (abv == null)
return inWord;
return new StringBuilder(abv).append(finalchar).toString();
}
// no punctuation
else {
//Reference map
String abv = abbreviations.get(inWord);
if (abv == null)
return inWord;
return abv;
}
}
public void shortenMessage( String inMessage ) {
String[] messageArray = inMessage.split("\s+") ;
for (String word : messageArray) {
System.out.println(shortenWord(word));
}
}
public static void main (String [] args) {
Shortener s = new Shortener();
s.shortenMessage("hello? any anyone thanks!");
}
}
输出:
lo?
ne
ne1
thx!
编辑:
根据 atommans 的回答,你基本上可以删除 shortenWord
方法,方法是像这样修改 shortenMessage
方法:
public void shortenMessage(String inMessage) {
for (Entry<String, String> entry:this.abbreviations.entrySet())
inMessage = inMessage.replaceAll(entry.getKey(), entry.getValue());
System.out.println(inMessage);
}
所以我看了看这个。首先,如果您可以选择更改文本文件的格式,我会将其更改为这样的格式(或 XML):
key1=value1
key2=value2
通过这样做,您以后可以使用 java 的 Properties.load(Reader)
。这将消除对文件进行任何手动解析的需要。'
如果通过任何更改您都无法选择更改格式,那么您将不得不自己解析它。类似下面的代码会这样做,并将结果放入名为 shortningRules
的 Map
中,稍后可以使用。
private void parseInput(FileReader reader) {
try (BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
String[] lineComponents = line.split(",");
this.shortningRules.put(lineComponents[0], lineComponents[1]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
当谈到实际缩短消息时,我可能会选择正则表达式方法,例如 \bKEY\b
其中关键字是您要缩短的单词。 \b
是正则表达式中的锚点,表示 word boundery,这意味着它不会匹配空格或标点符号。
进行缩短的整个代码将变成这样:
public void shortenMessage(String message) {
for (Entry<String, String> entry : shortningRules.entrySet()) {
message = message.replaceAll("\b" + entry.getKey() + "\b", entry.getValue());
}
System.out.println(message); //This should probably be a return statement instead of a sysout.
}
把它们放在一起会给你一些东西 this,这里我添加了一个 main
用于测试目的。
我已经为此工作了几天,但我无法取得任何进展。我试过使用 Scanner 和 BufferedReader 但没有成功。
基本上,我有一个工作方法 (shortenWord),它接受一个字符串并根据格式如下的文本文件缩短它:
hello,lo
any,ne
anyone,ne1
thanks,thx
它也考虑了标点符号,所以 'hello?' 变成了 'lo?' 等等
我需要能够读取字符串并单独翻译每个单词,因此 "hello? any anyone thanks!" 将变为 "lo? ne ne1 thx!",基本上使用我已经对字符串中的每个单词使用的方法。我拥有的代码将翻译第一个单词,但对其余单词不执行任何操作。我认为这与我的 BufferedReader 的工作方式有关。
import java.io.*;
public class Shortener {
private FileReader in ;
/*
* Default constructor that will load a default abbreviations text file.
*/
public Shortener() {
try {
in = new FileReader( "abbreviations.txt" );
}
catch ( Exception e ) {
System.out.println( e );
}
}
public String shortenWord( String inWord ) {
String punc = new String(",?.!;") ;
char finalchar = inWord.charAt(inWord.length()-1) ;
String outWord = new String() ;
BufferedReader abrv = new BufferedReader(in) ;
// ends in punctuation
if (punc.indexOf(finalchar) != -1 ) {
String sub = inWord.substring(0, inWord.length()-1) ;
outWord = sub + finalchar ;
try {
String line;
while ( (line = abrv.readLine()) != null ) {
String[] lineArray = line.split(",") ;
if ( line.contains(sub) ) {
outWord = lineArray[1] + finalchar ;
}
}
}
catch (IOException e) {
System.out.println(e) ;
}
}
// no punctuation
else {
outWord = inWord ;
try {
String line;
while( (line = abrv.readLine()) != null) {
String[] lineArray = line.split(",") ;
if ( line.contains(inWord) ) {
outWord = lineArray[1] ;
}
}
}
catch (IOException ioe) {
System.out.println(ioe) ;
}
}
return outWord;
}
public void shortenMessage( String inMessage ) {
String[] messageArray = inMessage.split("\s+") ;
for (String word : messageArray) {
System.out.println(shortenWord(word));
}
}
}
任何帮助,甚至是正确方向的推动,我们将不胜感激。
编辑:我试过在 shortenWord 方法的末尾关闭 BufferedReader,但它只是导致我在第一个表示 BufferedReader 已关闭的字词之后对字符串中的每个字词都出错。
我认为您可以使用 HashMap
获得更简单的解决方案。创建 Shortener
对象时将所有缩写读入地图,一旦有单词就引用它。单词将是 key
,缩写是 value
。像这样:
public class Shortener {
private FileReader in;
//the map
private HashMap<String, String> abbreviations;
/*
* Default constructor that will load a default abbreviations text file.
*/
public Shortener() {
//initialize the map
this.abbreviations = new HashMap<>();
try {
in = new FileReader("abbreviations.txt" );
BufferedReader abrv = new BufferedReader(in) ;
String line;
while ((line = abrv.readLine()) != null) {
String [] abv = line.split(",");
//If there is not two items in the file, the file is malformed
if (abv.length != 2) {
throw new IllegalArgumentException("Malformed abbreviation file");
}
//populate the map with the word as key and abbreviation as value
abbreviations.put(abv[0], abv[1]);
}
}
catch ( Exception e ) {
System.out.println( e );
}
}
public String shortenWord( String inWord ) {
String punc = new String(",?.!;") ;
char finalchar = inWord.charAt(inWord.length()-1) ;
// ends in punctuation
if (punc.indexOf(finalchar) != -1) {
String sub = inWord.substring(0, inWord.length() - 1);
//Reference map
String abv = abbreviations.get(sub);
if (abv == null)
return inWord;
return new StringBuilder(abv).append(finalchar).toString();
}
// no punctuation
else {
//Reference map
String abv = abbreviations.get(inWord);
if (abv == null)
return inWord;
return abv;
}
}
public void shortenMessage( String inMessage ) {
String[] messageArray = inMessage.split("\s+") ;
for (String word : messageArray) {
System.out.println(shortenWord(word));
}
}
public static void main (String [] args) {
Shortener s = new Shortener();
s.shortenMessage("hello? any anyone thanks!");
}
}
输出:
lo?
ne
ne1
thx!
编辑:
根据 atommans 的回答,你基本上可以删除 shortenWord
方法,方法是像这样修改 shortenMessage
方法:
public void shortenMessage(String inMessage) {
for (Entry<String, String> entry:this.abbreviations.entrySet())
inMessage = inMessage.replaceAll(entry.getKey(), entry.getValue());
System.out.println(inMessage);
}
所以我看了看这个。首先,如果您可以选择更改文本文件的格式,我会将其更改为这样的格式(或 XML):
key1=value1
key2=value2
通过这样做,您以后可以使用 java 的 Properties.load(Reader)
。这将消除对文件进行任何手动解析的需要。'
如果通过任何更改您都无法选择更改格式,那么您将不得不自己解析它。类似下面的代码会这样做,并将结果放入名为 shortningRules
的 Map
中,稍后可以使用。
private void parseInput(FileReader reader) {
try (BufferedReader br = new BufferedReader(reader)) {
String line;
while ((line = br.readLine()) != null) {
String[] lineComponents = line.split(",");
this.shortningRules.put(lineComponents[0], lineComponents[1]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
当谈到实际缩短消息时,我可能会选择正则表达式方法,例如 \bKEY\b
其中关键字是您要缩短的单词。 \b
是正则表达式中的锚点,表示 word boundery,这意味着它不会匹配空格或标点符号。
进行缩短的整个代码将变成这样:
public void shortenMessage(String message) {
for (Entry<String, String> entry : shortningRules.entrySet()) {
message = message.replaceAll("\b" + entry.getKey() + "\b", entry.getValue());
}
System.out.println(message); //This should probably be a return statement instead of a sysout.
}
把它们放在一起会给你一些东西 this,这里我添加了一个 main
用于测试目的。