web-dev-qa-db-fra.com

Utilisez Java et RegEx pour convertir le boîtier dans une chaîne

Problème: tourner

"My Testtext TARGETSTRING My Testtext" 

dans

"My Testtext targetstring My Testtext"

Perl prend en charge l'opération "\ L" qui peut être utilisée dans la chaîne de remplacement.

La classe de modèles ne prend pas en charge cette opération:

Constructions Perl non prises en charge par cette classe: [...] Les opérations de prétraitement\l\u,\L et\U. https://docs.Oracle.com/javase/10/docs/api/Java/util/regex/Pattern.html

36
Andreas

Vous ne pouvez pas le faire dans Java regex. Vous devez post-traiter manuellement en utilisant String.toUpperCase() et toLowerCase() à la place.

Voici un exemple de la façon dont vous utilisez l'expression régulière pour rechercher et mettre en majuscule des mots d'une longueur d'au moins 3 dans une phrase

    String text = "no way oh my god it cannot be";
    Matcher m = Pattern.compile("\\b\\w{3,}\\b").matcher(text);

    StringBuilder sb = new StringBuilder();
    int last = 0;
    while (m.find()) {
        sb.append(text.substring(last, m.start()));
        sb.append(m.group(0).toUpperCase());
        last = m.end();
    }
    sb.append(text.substring(last));

    System.out.println(sb.toString());
    // prints "no WAY oh my GOD it CANNOT be"

Remarque sur appendReplacement et appendTail

Notez que la solution ci-dessus utilise substring et gère un index tail, etc. En fait, vous pouvez vous en passer si vous utilisez Matcher.appendReplacement et appendTail.

    StringBuffer sb = new StringBuffer();
    while (m.find()) {
        m.appendReplacement(sb, m.group().toUpperCase());
    }
    m.appendTail(sb);

Notez comment sb est maintenant un StringBuffer au lieu de StringBuilder . Jusqu'à ce que Matcher fournisse StringBuilder surcharges, vous êtes bloqué avec le StringBuffer plus lent si vous souhaitez utiliser ces méthodes.

C'est à vous de décider si le compromis entre moins d'efficacité et une meilleure lisibilité en vaut la peine.

Voir également

57

Vous pouvez utiliser le regexp capturing group (si vous avez vraiment besoin d'utiliser regex, c'est-à-dire si "TARGETSTRING" est suffisamment complexe et "régulier" pour justifier d'être détecté par un regex).
Vous appliqueriez alors toLowerCase() au groupe # 1.

import Java.util.regex.*;

public class TargetToLowerCase {

  public static void main(String[] args) {
    StringBuilder sb= new StringBuilder(
            "my testtext TARGETSTRING my testtext");
    System.out.println(sb);
    String regex= "TARGETSTRING ";
    Pattern p = Pattern.compile(regex); // Create the pattern.
    Matcher matcher = p.matcher(sb); // Create the matcher.
    while (matcher.find()) {
      String buf= sb.substring(matcher.start(), matcher.end()).toLowerCase();
      sb.replace(matcher.start(), matcher.end(), buf);
    }
    System.out.println(sb);
  }
}
8
VonC

Java9 +

De Java 9+ vous pouvez utiliser String :: replaceAll où vous pouvez utiliser un Function<MatchResult, String> par exemple, nous utilisons l'exemple de polygenelubricants :

String text = "this is just a test which upper all short words";
String regex = "\\b\\w{0,3}\\b";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
String result = matcher.replaceAll(matche -> matche.group().toUpperCase());

System.out.println(result);

Ou juste :

String result = Pattern.compile(regex)
        .matcher(text)
        .replaceAll(matche -> matche.group().toUpperCase());

Sortie

this IS just A test which upper ALL short words
     ^^      ^                  ^^^
6
YCF_L

Pour ce faire au niveau regexp, vous devez utiliser \U pour activer le mode majuscule et \E pour l'éteindre. Voici un exemple d'utilisation de cette fonctionnalité dans IntelliJ IDEA find-and-replace boîte de dialogue qui transforme l'ensemble des champs de classe en assertions JUnit (à IDE tooltip est le résultat de find-and-replace transformation):

enter image description here

5
Andriy Kryvtsun

Que diriez-vous de cette fonction de transformation dans "Java 8"

/**
 * Searches the given pattern in the given src string and applies the txr to the
 * matches
 * 
 * @param src     The string to be converted
 * @param pattern the pattern for which the transformers to be applied.
 * @param txr     The transformers for the mathed patterns.
 * @return The result after applying the transformation.
 */
private static String fromTo(String src, String pattern, Function<String, String> txr) {
    Matcher m = Pattern.compile(pattern).matcher(src);

    StringBuilder sb = new StringBuilder();
    int last = 0;

    while (m.find()) {
        sb.append(src.substring(last, m.start()));
        sb.append(txr.apply(m.group(0)));
        last = m.end();
    }
    sb.append(src.substring(last));
    return sb.toString();
}
0
Kannan Ramamoorthy