在Java中使用正则表达式查找最后一个匹配的索引

11

我有一个字符串%/O^/O%/O,我想找到最后一个斜线“/”来分割这个字符串。我的第一次尝试是:\/[POL]$,但它会包括明显不需要的字符"O"。有人有什么建议吗?

7个回答

13

我同意使用标准的String.lastIndexOf()方法是你最好的选择,但最近我需要使用正则表达式部分(即我想要在字符串中找到最后一个非字母数字字符)。

我最终自己写了这个功能,并且想分享一下,希望能帮助其他人:

/**
 * Indicates that a String search operation yielded no results.
 */
public static final int NOT_FOUND = -1;

/**
 * Version of lastIndexOf that uses regular expressions for searching.
 * 
 * @param str String in which to search for the pattern.
 * @param toFind Pattern to locate.
 * @return The index of the requested pattern, if found; NOT_FOUND (-1) otherwise.
 */
public static int lastIndexOfRegex(String str, String toFind)
{
    Pattern pattern = Pattern.compile(toFind);
    Matcher matcher = pattern.matcher(str);
    
    // Default to the NOT_FOUND constant
    int lastIndex = NOT_FOUND;
    
    // Search for the given pattern
    while (matcher.find())
    {
        lastIndex = matcher.start();
    }
    
    return lastIndex;
}

/**
 * Finds the last index of the given regular expression pattern in the given string,
 * starting from the given index (and conceptually going backwards).
 * 
 * @param str String in which to search for the pattern.
 * @param toFind Pattern to locate.
 * @param fromIndex Maximum allowed index.
 * @return The index of the requested pattern, if found; NOT_FOUND (-1) otherwise.
 */
public static int lastIndexOfRegex(String str, String toFind, int fromIndex)
{
    // Limit the search by searching on a suitable substring
    return lastIndexOfRegex(str.substring(0, fromIndex), toFind);
}

此外,通过首先反转输入字符串,然后获取第一个组的结束索引(而不是遍历所有组),可能可以使此方法更快。

但是,要做到这一点,您还必须反转模式;在某些情况下,这可能很简单(如搜索单个字符的情况),但在其他情况下可能会出现问题。


11
/(?=[^/]*$)

会匹配一个后面没有跟着其他//。要使用它进行拆分,请使用

String[] splitArray = subjectString.split("/(?=[^/]*$)");

6

核心问题很好,尽管你提供的示例不需要它。Java的indexOf方法不接受正则表达式。仅回答问题的主题部分,以下是你需要的内容:

/**
* Version of indexOf that uses regular expressions for the search
* by Julian Cochran.
*/
public static int indexOfRegex(String message, String toFind) {
  // Need to add an extra character to message because to ensure
  // split works if toFind is right at the end of the message.
  message = message + " ";
  String separated[] = message.split(toFind);
  if (separated == null ||
      separated.length == 0 ||
      separated.length == 1) {
    return -1;
  }
  return separated[0].length();
}

如果您需要最后一个索引:

/**
* Version of lastIndexOf that uses regular expressions for
* the search by Julian Cochran.
*/
public static int lastIndexOfRegex(String message, String toFind) {
  // Need to add an extra character to message because to ensure
  // split works if toFind is right at the end of the message.
  message = message + " ";
  String separated[] = message.split(toFind);
  if (separated == null ||
      separated.length == 0 ||
      separated.length == 1) {
    return -1;
  }
  return separated[separated.length - 1].length();
}

@Julian Cochran。我买了一本二手书,上面有你的名字,里面还有你和你的女儿、儿子的照片?如果是你的话,我想把照片送给你。很抱歉在这里打扰,但没有其他方式可以找到你... - clg4

4

你需要使用正则表达式吗?使用String.lastIndexOf("/")可以找到索引,然后使用String.substring(int start, int end)和结果一起使用吗?或者你的实际数据不同且更加复杂,需要使用正则表达式吗?根据你提供的内容,在最后一个 / 上分割字符串的代码如下:

int lastSlash = mystring.lastIndexOf("/");
String start = mystring.substring(0, lastSlash);
String end = mystring.substring(lastSlash + 1, mystring.length);

2
如果你只是想找到一个字符的最后一个实例,使用正则表达式太过复杂了,你应该直接使用字符串的lastIndexOf方法。
int pos = myString.lastIndexOf('/');

2
+1 - 这更有效率。另一方面,找到最后一个 / 的正则表达式可以直接传递给 .split()——这可能是个人口味问题,哪种更易读(与 justkt 的解决方案进行比较)。 - Tim Pietzcker

0

参考:https://github.com/apache/commons-lang/pull/273/files

   public static int lastIndexOfAnyChar( final CharSequence str,final String searchChars) {
    return searchChars == null ? INDEX_NOT_FOUND : lastIndexOfAnyChar(str,searchChars.toCharArray());
}

/**
 * <p>Search a CharSequence to find the last index of any
 * character in the given set of characters.</p>
 *
 * <p>A {@code null} String will return {@code -1}.
 * A {@code null} or zero length search array will return {@code -1}.</p>
 *
 * <pre>
 * StringUtils.lastIndexOfAnyChar(null, *)                = -1
 * StringUtils.lastIndexOfAnyChar("", *)                  = -1
 * StringUtils.lastIndexOfAnyChar(*, null)                = -1
 * StringUtils.lastIndexOfAnyChar(*, [])                  = -1
 * StringUtils.lastIndexOfAnyChar("zzabyycdxx",['z','a']) = 2
 * StringUtils.lastIndexOfAnyChar("zzabyycdxx",['b','y']) = 5
 * StringUtils.lastIndexOfAnyChar("aba", ['z'])           = -1
 * </pre>
 *
 * @param cs  the CharSequence to check, may be null
 * @param searchChars  the chars to search for, may be null
 * @return the last index of any of the chars, -1 if no match or null input
 */
public static int lastIndexOfAnyChar( final CharSequence str,final char... searchChars) {
    if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
        return INDEX_NOT_FOUND;
    }
    int csLen = str.length();
    int csLast = csLen - 1;
    int searchLen = searchChars.length;
    int searchLast = searchLen - 1;
    for (int i = csLast ; i >= 0 ; i--) {
        char ch = str.charAt(i);
        for (int j = 0; j < searchLen; j++) {
            if (searchChars[j] == ch) {
                if (i < csLast && j < searchLast &&  Character.isHighSurrogate(ch) ) {
                    // ch is a supplementary character
                    if (searchChars[j + 1] == str.charAt(i + 1)) {
                        return i;
                    }
                } else {
                    return i;
                }
            }
        }
    }
    return INDEX_NOT_FOUND;
}

0
        String name ="rami is good boy, and he is working for andorid,is completed";
    int lastSlash = name.lastIndexOf("is");
    String start = name.substring(0, lastSlash);
    String end = name.substring(lastSlash + 1, name.length());
    StringBuffer sb = new StringBuffer(name);
    sb.replace(start.length(), name.lastIndexOf(end)+1, "");

    System.out.println(sb.toString());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接