【问题标题】:Regex for replacing specific characters before and after specific substring用于在特定子字符串之前和之后替换特定字符的正则表达式
【发布时间】:2015-04-09 01:14:44
【问题描述】:

我正在学习 Java CodingBat 练习。 Here是我刚刚完成的:

给定一个字符串和一个非空单词字符串,返回一个由字符串中每个单词出现之前和之后的每个字符组成的字符串。忽略单词前后没有字符的情况,如果字符在两个单词之间,它可能会被包含两次。

我的代码,有效:

public String wordEnds(String str, String word){

    String s = "";
    String n = " " + str + " "; //To avoid OOB exceptions

    int sL = str.length();
    int wL = word.length();
    int nL = n.length();

    int i = 1;

    while (i < nL - 1) {

        if (n.substring(i, i + wL).equals(word)) {
            s += n.charAt(i - 1);
            s += n.charAt(i + wL);
            i += wL;
        } else {
            i++;
        }
    }

    s = s.replaceAll("\\s", "");

    return s;
}

我的问题是关于正则表达式。我想知道上述是否可以使用正则表达式语句,如果可以,如何?

【问题讨论】:

  • 这个问题可能很难用 Java 正则表达式解决,因为匹配可能会重叠,例如abcXY1XYijkXY 上匹配会将cXY11XYi 作为组。
  • 好问题,顺便说一句^ ^
  • 添加一些输入和预期输出
  • UTF-16 是可变宽度,而不是固定宽度。每个字符占用一个或两个代码单元。所以chatAt 是错误的。

标签: java regex string


【解决方案1】:

您可以使用 Java 正则表达式对象 PatternMatcher 来执行此操作。

public class CharBeforeAndAfterSubstring {
    public static String wordEnds(String str, String word) {
        java.util.regex.Pattern p = java.util.regex.Pattern.compile(word);
        java.util.regex.Matcher m = p.matcher(str);
        StringBuilder beforeAfter = new StringBuilder();

        for (int startIndex = 0; m.find(startIndex); startIndex = m.start() + 1) {
            if (m.start() - 1 > -1)
                beforeAfter.append(Character.toChars(str.codePointAt(m.start() - 1)));
            if (m.end() < str.length())
                beforeAfter.append(Character.toChars(str.codePointAt(m.end())));
        }

        return beforeAfter.toString();
    } 
    public static void main(String[] args) {
        String x = "abcXY1XYijk";
        String y = "XY";
        System.out.println(wordEnds(x, y));

    }
} 

【讨论】:

  • 我很欣赏这个问题含糊不清的“可能”部分。在这种情况下,应该包含,否则测试失败
  • @alanbuchanan 已编辑答案,请查看。添加了更多的索引逻辑以确保正确计算重叠。
  • 这不适用于 16/17 个 ?Unicode? 平面。请停止使用charAt:它不适合用途。
  • 谢谢@tchrist。进行了修正。这是一个初学者的问题,所以没有太多关于 unicode 的问题。
【解决方案2】:
(?=(.|^)XY(.|$))

试试这个。只需抓取捕获并删除 Noneempty 值。查看演示。

https://regex101.com/r/sJ9gM7/73

【讨论】:

  • 这没有考虑到XY 可能是其他东西,正如问题中str 所定义的那样
【解决方案3】:

要在一个字符串中每次出现之前和之后获取包含该字符的字符串,您可以使用正则表达式:

"(^|.)" + str + "(.|$)"

然后您可以遍历这些组并将它们连接起来。

此表达式将查找(^|.),字符串的开头^ 或任何字符.,后跟str 值,后跟(.|$),任何字符. 或结尾字符串$

你可以试试这样的:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public String wordEnds(String str, String word){
    Pattern p = Pattern.compile("(.)" + str + "(.)");
    Matcher m = p.matcher(word);
    String result = "";
    int i = 0;
    while(m.find()) {
        result += m.group(i++);
    }
    return result;
}

【讨论】:

  • return a string made of each char just before and just after every appearance of the word in the string 效果如何?
  • @Scary Wombat 感谢您的反馈。你说的对。我正在替换而不是只返回那些字符,这与所要求的相反。更新了答案。
  • 你的代码在codingbat.com/prob/p147538 的大部分测试都失败了,OP 试图从中学习。
  • @user883499 更新了表达式中的逻辑。
猜你喜欢
  • 1970-01-01
  • 2023-02-10
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
  • 2012-09-04
  • 2021-11-21
  • 1970-01-01
  • 2020-06-30
相关资源
最近更新 更多