【问题标题】:Ignoring upper/lowercase strings忽略大写/小写字符串
【发布时间】:2014-12-02 01:56:16
【问题描述】:

我的目标是将句子中任何形式的“java”一词更改为“JAVA”。我已经完成了所有工作,但我的代码无法在混合情况下读取,例如:Java、JAva 等。我知道我想使用 toUpperCase 和 toLowerCase 或 equalsIgnoreCase 但我不确定如何正确使用它。我不允许使用replace或replace all,老师想要子字符串方法。

    Scanner input=new Scanner(System.in);
    System.out.println("Enter a sentence with words including java");
    String sentence=input.nextLine();

    String find="java";
    String replace="JAVA";
    String result="";
    int n;
    do{
        n=sentence.indexOf(find);
        if(n!=-1){
            result =sentence.substring(0,n);
            result=result +replace;
            result = result + sentence.substring(n+find.length());
            sentence=result;            
        }
    }while(n!=-1);
    System.out.println(sentence);
}

}

【问题讨论】:

    标签: java substring


    【解决方案1】:

    您不能使用 String.indexOf 来执行此操作,因为它区分大小写。

    简单的解决方案是使用不区分大小写模式的正则表达式;例如

    Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher(str).replaceAll(repl);
    

    这也有利于避免您当前用于替换的混乱字符串。


    在您的示例中,您的输入字符串也可以作为正则表达式......因为它不包含任何正则表达式元字符。如果是这样,那么简单的解决方法是使用Pattern.quote(str),它将元字符视为文字匹配。

    String.replaceAll(...) 是一种对字符串进行正则表达式替换的“便捷方法”,这一点也毫无价值,尽管您不能在示例中使用它,因为它会区分大小写。


    为了记录,这是一个通过字符串打击来完成工作的部分解决方案。 @ben - 这是供您阅读和理解的......不要复制。特意去掉注释,鼓励大家仔细阅读。

    // WARNING ... UNTESTED CODE
    String input = ...
    String target = ...
    String replacement = ...
    String inputLc = input.lowerCase();
    String targetLc = target.lowerCase();
    int pos = 0;
    int pos2;
    while ((pos2 = inputLc.indexOf(targetLc, pos)) != -1) {
        if (pos2 - pos > 0) {
            result += input.substring(pos, pos2);
        }
        result += replacement;
        pos = pos2 + target.length();
    }
    if (pos < input.length()) {
        result += input.substring(pos);
    }
    

    对于result,使用StringBuilder 而不是String 可能更有效。

    【讨论】:

    • 对不起!忘了提我不能使用replaceAll。老师要我只用子串法。
    • @Stephen C,有一种方法可以通过包含"(?i)" 以不区分大小写的方式使用String.replaceAll,正如我在回答中所展示的那样
    • @ben - 实际上,我希望您的老师希望您自己解决所有问题!
    【解决方案2】:

    您可以使用toUpperCase() 吗?试试这个

     Scanner input=new Scanner(System.in);
        System.out.println("Enter a sentence with words including java");
        String sentence=input.nextLine();
    
        String find="java";
        String replace="JAVA";
        String result="";
    
        result = sentence.toLowerCase();
        result = result.replace(find,replace);
        System.out.println(result);
    }
    

    回复结果 :))

    更新:基于

    我已完成所有工作,但我的代码在混合情况下无法读取 例如:Java、JAva等

    你可以使用你的代码

       Scanner input=new Scanner(System.in);
        System.out.println("Enter a sentence with words including java");
        String sentence=input.nextLine();
    
        String find="java";
        String replace="JAVA";
        String result="";
        int n;
        do{
            //for you to ignore(converts the sentence to lowercase) either lower or upper case in your sentence then do the nxt process
            sentence = sentence.toLowerCase();
    
            n=sentence.indexOf(find);
            if(n!=-1){
                result =sentence.substring(0,n);
                result=result +replace;
                result = result + sentence.substring(n+find.length());
                sentence=result;            
            }
        }while(n!=-1);
        System.out.println(sentence);
    }
    

    更新 2:我将 toLowerCase 转换放在循环之外。

    public static void main(String[] args){
    
                String sentence = "Hello my name is JAva im a jaVa Man with a jAvA java Ice cream";
                String find="java";
                String replace="JAVA";
                String result="";
                int n;
                //for you to ignore(converts the sentence to lowercase) either lower or upper case in your sentence then do the nxt process
                sentence = sentence.toLowerCase();
                System.out.println(sentence);
    
                do{
    
    
                    n=sentence.indexOf(find);
                    if(n!=-1){
                        result =sentence.substring(0,n);
                        result=result +replace;
                        result = result + sentence.substring(n+find.length());
                        sentence=result;            
                    }
                }while(n!=-1);
    
                System.out.println(sentence);
        }
    

    结果

    你好,我的名字是 java,我是一个 java 男人,有一个 java java 冰淇淋

    你好,我叫 JAVA,我是一个 JAVA 男人,吃着 JAVA JAVA 冰淇淋

    【讨论】:

    • 对不起!不能用replace,只能用substring方法。
    • 更新的部分将不起作用,因为它将整个句子转换为小写,从而改变的不仅仅是“java”的字符串匹配变体
    • 你想对这个句子做什么?我以为您想将句子中的所有(java、JavaA、jaVa 等)转换为 JAVA(大写)。
    • 我将句子转换为小写以忽略区分大小写
    • 有趣。最终的答案当然是错误的,但我们会留给 Ben 的老师/马克笔指出缺陷。 :-)
    【解决方案3】:

    一个快速的解决方案是完全删除您的do/while 循环,只需使用不区分大小写的正则表达式和String.replaceAll(),例如:

    sentence = sentence.replaceAll("(?i)java", "JAVA");
    System.out.println(sentence);
    

    或者,更一般的,根据你的变量命名:

    sentence = sentence.replaceAll("(?i)" + find, replace);
    System.out.println(sentence);
    

    Sample Program

    编辑:

    根据你的cmets,如果你需要使用substring方法,这里有一种方法。

    首先,由于String.indexOf进行区分大小写的比较,你可以编写自己的不区分大小写的方法,我们称之为indexOfIgnoreCase()。这个方法看起来像:

    // Find the index of the first occurrence of the String find within the String str, starting from start index
    // Return -1 if no match is found
    int indexOfIgnoreCase(String str, String find, int start) {
        for(int i = start; i < str.length(); i++) {
            if(str.substring(i, i + find.length()).equalsIgnoreCase(find)) {
                return i;
            }
        }
        return -1;
    }
    

    那么,您可以通过以下方式使用此方法。

    你找到你需要的词的索引,然后你把这个词之前的字符串部分(直到找到的索引)添加到结果中,然后你添加你找到的词的替换版本,然后你添加找到的单词之后的其余字符串。

    最后,根据找到的单词的长度更新起始搜索索引。

    String find = "java";
    String replace = "JAVA";
    int index = 0;
    while(index + find.length() <= sentence.length()) {
        index = indexOfIgnoreCase(sentence, find, index);       // use the custom indexOf method here
        if(index == -1) {
            break;
        }
        sentence = sentence.substring(0, index) +               // copy the string up to the found word
                   replace +                                    // replace the found word
                   sentence.substring(index + find.length());   // copy the remaining part of the string
        index += find.length();
    }
    System.out.println(sentence);
    

    Sample Program

    您可以使用StringBuilder 来提高效率,因为+ 运算符会在每个连接上创建一个新字符串。 Read more here

    此外,您可以将indexOfIgnoreCase 中的逻辑和其余代码组合在一个方法中,例如:

    String find = "java";
    String replace = "JAVA";
    StringBuilder sb = new StringBuilder();
    int i = 0;
    while(i + find.length() <= sentence.length()) {
        // if found a match, add the replacement and update the index accordingly
        if(sentence.substring(i, i + find.length()).equalsIgnoreCase(find)) {
            sb.append(replace);
            i += find.length();
        } 
        // otherwise add the current character and update the index accordingly
        else {
            sb.append(sentence.charAt(i));
            i++;
        }
    }
    sb.append(sentence.substring(i)); // append the rest of the string
    sentence = sb.toString();
    System.out.println(sentence);
    

    【讨论】:

    • 这个问题是你正在“规范化”字间距作为副作用。此外,如果在 find 单词之前或之后有一个标点符号,它也不起作用。
    • 是的,你是对的,我想出了一个更好的解决方案
    • 对不起!忘了提我不能使用replaceAll。老师要我只用子串法。
    • @ben,看看我的编辑。我相信这就是您正在寻找的。​​span>
    • @nem 感谢您的所有帮助!不幸的是,我还没有学习 indexOfIgnoreCase 并且我也不允许使用 stringbuilder (我的错是没有更清楚地说明我的方向,用完了时间 atm)所以我不能使用你的任何建议。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-01-29
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 2013-04-11
    • 2012-12-10
    • 1970-01-01
    相关资源
    最近更新 更多