Use regex to replace all occurrences with CASE_INSENSITIVE (regardless of uppercase and lowercase)

5

I try to make a method that finds and replaces words using regular expressions. The point is that I must be able to find and replace the word regardless of whether it has uppercase letters or not. This is the code that I carry:

public String reemplazar(String cadena,JFrame frame){
    StringBuffer reemplazar = new StringBuffer();
    StringBuffer buscar = new StringBuffer();
    StringBuffer respuesta = new StringBuffer();

    DlgReemplazar dlgReemplazar = new DlgReemplazar(
        frame, true, buscar, reemplazar, constantesGUI.REEMPLAZAR, respuesta
    );
    dlgReemplazar.setVisible(true);

    Pattern pat = Pattern.compile(buscar.toString(), Pattern.CASE_INSENSITIVE);
    Matcher mat = pat.matcher(cadena);

    if (mat.find() == true) {
        cadena = cadena.replaceAll(
            String.valueOf(buscar), String.valueOf(reemplazar)
        );
    }else{
        JOptionPane.showMessageDialog(null, "No se encontro el texto");
    }      
    return cadena;
}
    
asked by user3912930 09.11.2016 в 02:51
source

1 answer

6

The first point to correct is that you have to escape the special characters that may be in the variable. For example, if the user enters [hola] , I understand that I should look for that literal text, and not just one of those 4 characters.

To obtain a literal pattern from a string, use Pattern.quote () .

String patronBuscado = Pattern.quote(buscar.toString());
  • You would not need to escape if you use the Pattern switch. LITERAL , although I personally prefer to do it without this modifier to make it clearer or allow only a part of the pattern to escape.

And the same applies for the replacement, where you should use Matcher.quoteReplacement () .

String patronReemplazo = Matcher.quoteReplacement(reemplazar.toString());


Now yes, let's go to the main thing. As you may have seen, String.replaceAll () does not accept modifiers such as Pattern.CASE_INSENSITIVE , nor% Pattern , only strings.

There are 3 ways to replace it regardless of uppercase and lowercase.

  • Passing the online switch as (?i) into the regular expression:

    cadena = cadena.replaceAll( "(?i)" + patronBuscado, patronReemplazo);
    
  • Use Matcher.replaceAll () about a compiled regular expression:

    Pattern pat = Pattern.compile(patronBuscado, Pattern.CASE_INSENSITIVE);
    Matcher mat = pat.matcher(cadena);
    cadena = mat.replaceAll(patronReemplazo);
    
  • Alternatively you can use the methods Matcher.appendReplacement () and Matcher.appendTail () to be replaced with a StringBuffer and have more control over each of the replacements. However, this is unnecessary if you simply want to replace all occurrences with the same value.


  • Lastly, it must be taken into account that Pattern.CASE_INSENSITIVE only works in the ASCII range. If you would also like to replace accents, you should add Pattern.UNICODE_CASE (or the online modifier (?iu) ):

    Pattern pat = Pattern.compile(patronBuscado, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    

    Code:

    String cadena = "Respuesta de SO en inglés";
    
    StringBuffer buscar = new StringBuffer("EN INGLÉS");
    String patronBuscado = Pattern.quote(buscar.toString());
    
    StringBuffer reemplazar = new StringBuffer("en español");
    String patronReemplazo = Matcher.quoteReplacement(reemplazar.toString());
    
    Pattern pat = Pattern.compile(patronBuscado, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
    Matcher mat = pat.matcher(cadena);
    
    if (mat.find()) {
        cadena = mat.replaceAll(patronReemplazo);
        System.out.println("Resultado: " + cadena);
    } else {
        System.out.println("No se encontro el texto");
    }
    

    Demo:

    Ideone.com

        
    answered by 09.11.2016 / 03:20
    source