简体   繁体   English

匹配字符串中单词的最后一次出现

[英]Match the last occurrence of a word in a string

Currently, I am implementing a textbox in java swing, which highlights the keywords. 当前,我正在用java swing实现一个文本框,该文本框突出显示了关键字。 I referenced to the 2nd answer given in this question . 我参考了这个问题给出的第二个答案。 However, I want only the last occurrence of the word to be highlighted. 但是,我只希望突出显示单词的最后一次出现。

For example, when the user is typing "I have swimming at school at 7pm" , I want the textbox to highlight only the second "at" . 例如,当用户键入"I have swimming at school at 7pm" ,我希望文本框仅突出显示第二个"at" I have tried using the negative lookahead in the regex. 我曾尝试在正则表达式中使用负前瞻。 But it is not working. 但这是行不通的。

I used (at(?!.at)|from|by))) instead of (at|from|by) 我用(at(?!.at)|from|by)))代替(at|from|by)

What I have tried (Referenced from the link provided): 我尝试了什么(从提供的链接中引用):

  if (wordR == after || String.valueOf(text.charAt(wordR)).matches("\\W")) {
                    if (text.substring(wordL, wordR).matches("(\\W)*(at(?!.at)|from|by)"))
                        setCharacterAttributes(wordL, wordR - wordL, attr, false);
                    else
                        setCharacterAttributes(wordL, wordR - wordL, attrBlack, false);
                    wordL = wordR;
                }

I think the regex is not working as the checking is happening while the user is typing, but am not sure on how to solve this problem. 我认为正则表达式无法正常工作,因为用户在键入时会进行检查,但是不确定如何解决此问题。

Why don't you use this method : 为什么不使用这种方法

 public int lastIndexOf(String str) 

Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index. 返回最后一次出现的指定子字符串在此字符串内的索引,从指定索引开始向后搜索。

As in: 如:

System.out.println("index =  " + "I have swimming at school at 7pm".lastIndexOf("at"));

You can use the value returned by lastIndexOf() to set the attributes of the String in your Swing component, but obviously, you'll need to reset what you've previously done as explained here: Resetting attributes in a Document after inserting a String 您可以使用lastIndexOf()返回的值来设置Swing组件中String的属性,但是显然,您需要按以下说明重置以前所做的操作: 插入String后在Document中重置属性

If you don't do this, every occurrence of the word will remain highlighted. 如果您不这样做,则该单词的每次出现都会突出显示。

Do you have to use regular expressions? 您必须使用正则表达式吗? indexOf has a starting position as its second parameter from where to start the search. indexOf具有一个起始位置作为从其开始搜索的第二个参数。 You can just fill it with the position of the first hit. 您只需要填写第一个匹配项的位置即可。 Example script: 示例脚本:

String haystack = "I have swimming at school at 7pm";
String needle = " at ";
int pos2 = haystack.indexOf(needle, haystack.indexOf(needle) + 1);
if (pos2 > -1) {
    System.out.println("Found second '" + needle + "' at position " + pos2);
} else {
    System.out.println("Could not find second '" + needle + '"');
}

Outputs: Found second ' at ' at position 25 输出: Found second ' at ' at position 25

The procedure becomes a little more complicated if you also want to hit at. 如果您也想打的话,程序会变得有些复杂at. , at, , at? at, 、、 at? and at! at! , but the basic principle stays the same. ,但基本原理保持不变。

Basically you can use the a greedy quantifier before the word you search: 基本上,您可以在搜索词前使用贪婪量词:

Pattern p = Pattern.compile(".*\\b(at|from|by)\\b");
String s = "I have swimming at school at 7pm";
Matcher m = p.matcher(s);
if (m.lookingAt()) {
    System.out.println(m.group(1));
}

Because .* is greedy, you obtain the last occurrence (or the first from the end of the string). 因为.*是贪婪的,所以您获得了最后一个匹配项(或字符串末尾的第一个匹配项)。

The main interest of this way is that it continues to work whatever the characters before or after the words you search like punctuation characters because the alternation is surrounded by word boundaries. 这种方式的主要好处是,无论您搜索的单词之前还是之后的字符都像标点符号一样,它都能继续工作,因为交替词被单词边界包围。 Word boundaries avoid false positive for example when at is included in an other word. 单词边界可以避免误报,例如当另一个单词中包含at时。

Note: in a replacement context, you need to capture the start of the string. 注意:在替换上下文中,您需要捕获字符串的开头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM