Javafx 8替换textarea中的文本并保持格式
我们正在尝试替换TextArea中的拼写错误的单词,当该单词位于文本行的末尾并有回车符时,该过程将导致其他拼写错误的单词无法按预期替换
We are trying to replace misspelled words in the TextArea and when the word is at the end of a line of text and has a carriage return the process is failing other misspelled words are replace as expected
示例文字
好吧,我们在这里进行拼写测试吗? 但我担心字典是限制因素吗?
Example Text
Well are we reddy for production the spell test is here but I fear the dictionary is the limiting factor ?
这是林abov中的回车测试
Here is the carriage return test in the lin abov
加盖的单词会测试慢动作,并且不要忘记日期
Hypenated words test slow-motion and lets not forget the date
在拼写错误的单词 abov 之后,我们在ArrayList中有一个回车符,文本看起来像这样
Just after the misspelled word abov we have a carriage return in the ArrayList the text looks like this
in,the,lin,abov
in, the, lin, abov
因为此拼写错误的单词后没有逗号,替换代码也删除了拼写错误的单词Hypenated,因为替换代码将"abov& Hypenated" 视为具有相同的索引
Because this misspelled word has no comma after it the replacement code also takes out the misspelled word Hypenated because the replacement code sees "abov & Hypenated" as being at the same Index
运行替换代码的结果
Result of running the replacement code
这是单词test上方林中的回车测试
Here is the carriage return test in the lin above words test
如果这行代码是strArray = line.split(" ");
更改为此strArray = line.split("\\s");
,问题就消失了,但是TextArea中所有回车符的格式也被删除了,这不是期望的结果
If this line of code strArray = line.split(" ");
is changed to this strArray = line.split("\\s");
the issue goes away but so does the formatting in the TextArea all the carriage returns are deleted which is not a desired outcome
问题是如何处理格式问题并仍然替换拼写错误的单词?
注意:仅当拼写错误的单词位于句子的末尾时,才会发生这种情况,例如,拼写错误的单词"lin" 将按需要替换
该项目的代码行过多,因此我们仅发布导致结果不令人满意的代码
我们尝试仅使用String []数组,但很少成功或没有成功
The question is how to deal with the formatting issue and still replace the misspelled words?
Side note this only happens when the misspelled word is at the end of a sentences for example the misspelled word "lin" will be replaced as desired
We have an excessive number of lines of code for this project so we are only posting the code that is causing the unsatisfactory results
We tried using just a String[ ] array with little or no success
@FXML
private void onReplace(){
if(txtReplacementWord.getText().isEmpty()){
txtMessage.setText("No Replacement Word");
return;
}
cboMisspelledWord.getItems().remove(txtWordToReplace.getText());
// Line Above Removes misspelled word from cboMisspelledWord
// ==========================================================
String line = txaDiaryEntry.getText();
strArray = line.split(" ");
List<String> list = new ArrayList<>(Arrays.asList(strArray));
for (int R = 0; R < list.size(); R++) {
if(list.get(R).contains(txtWordToReplace.getText())){
theIndex = R;
System.out.println("## dex "+theIndex);//For testing
}
}
System.out.println("list "+list);//For testing
list.remove(theIndex);
list.add(theIndex,txtReplacementWord.getText());
sb = new StringBuilder();
for (String addWord : list) {
sb.append(addWord);
sb.append(" ");
}
txaDiaryEntry.setText(sb.toString());
txtMessage.setText("");
txtReplacementWord.setText("");
txtWordToReplace.setText("");
cboCorrectSpelling.getItems().clear();
cboMisspelledWord.requestFocus();
// Code above replaces misspelled word with correct spelling in TextArea
// =====================================================================
if(cboMisspelledWord.getItems().isEmpty()){
onCheckSpelling();
}
}
请勿使用split
.这样,您就可以松散单词之间有关内容的信息.而是创建一个Pattern
匹配词,并确保还要在匹配项之间复制子字符串.这样,您就不会在那里丢失任何信息.
Don't use split
. This way you loose the info about the content between the words. Instead create a Pattern
matching words and make sure to also copy the substrings between matches. This way you don't loose any info there.
为简单起见,以下示例通过在Map
中简单查找替换来替换替换逻辑,但足以证明该方法:
The following example replaces the replacement logic with simply looking for replacements in a Map
for simplicity, but it should be sufficient to demonstrate the approach:
public void start(Stage primaryStage) throws Exception {
TextArea textArea = new TextArea(
"Well are we reddy for production the spell test is here but I fear the dictionary is the limiting factor ?\n"
+ "\n" + "Here is the carriage return test in the lin abov\n" + "\n"
+ "Hypenated words test slow-motion and lets not forget the date");
Map<String, String> replacements = new HashMap<>();
replacements.put("lin", "line");
replacements.put("abov", "above");
Pattern pattern = Pattern.compile("\\S+"); // pattern matching words (=non-whitespace sequences in this case)
Button button = new Button("Replace");
button.setOnAction(evt -> {
String text = textArea.getText();
StringBuilder sb = new StringBuilder();
Matcher matcher = pattern.matcher(text);
int lastEnd = 0;
while (matcher.find()) {
int startIndex = matcher.start();
if (startIndex > lastEnd) {
// add missing whitespace chars
sb.append(text.substring(lastEnd, startIndex));
}
// replace text, if necessary
String group = matcher.group();
String result = replacements.get(group);
sb.append(result == null ? group : result);
lastEnd = matcher.end();
}
sb.append(text.substring(lastEnd));
textArea.setText(sb.toString());
});
final Scene scene = new Scene(new VBox(textArea, button));
primaryStage.setScene(scene);
primaryStage.show();
}