1 votes

Existe-t-il une expression régulière pour trouver/remplacer le début commun de toutes les lignes d'un bloc de texte ?

Imaginez cette chaîne :

    if(editorPart instanceof ITextEditor){
        ITextEditor editor = (ITextEditor)editorPart;
        selection = (ITextSelection) editor.getSelectionProvider().getSelection();
    }else if( editorPart instanceof MultiPageEditorPart){
        //this would be the case for the XML editor
        selection = (ITextSelection) editorPart.getEditorSite().getSelectionProvider().getSelection();
    }

Je peux voir, visuellement, que le début "commun" dans chacune de ces lignes est constitué de deux caractères de tabulation. Existe-t-il une expression régulière qui remplacerait -- uniquement au début de chaque ligne (y compris la première et la dernière ligne), ce début commun, de sorte qu'après l'expression régulière, je me retrouverais avec la même chaîne, mais essentiellement non indentée ?

Je ne peux pas simplement rechercher "deux tabulations" dans ce cas, car il peut y avoir deux tabulations ailleurs dans le texte, mais pas au début d'une ligne.

J'ai implémenté cette fonctionnalité avec une méthode différente mais j'ai pensé que ce serait un défi regex amusant, si c'est possible.

5voto

David Crawshaw Points 4842

Le site ^ dans une expression régulière correspond au début d'une ligne. Donc :

/^\t\t//g

Supprime deux tabulations au début d'une ligne.

1voto

David Z Points 49476

En général (c'est-à-dire si vous voulez faire correspondre un préfixe arbitraire, pas nécessairement deux tabulations), il peut y avoir ou non un moyen. Cela dépend du moteur d'expression régulière que vous utilisez. J'imagine que quelque chose d'à peu près comme este pourrait travail :

\B^(.+).*?$(?:^\1.*?$)+\E

Notez que je me suis probablement trompé dans la syntaxe regex, considérez cela comme une sorte de pseudo-code regex ( \B est le début de la chaîne, ^ est le début de la ligne, $ est la fin de la ligne, \E est la fin de la chaîne)

Mais ce n'est vraiment pas un travail que je ferais avec une expression régulière. Un simple analyseur syntaxique caractère par caractère semble bien mieux convenir.

1voto

ojrac Points 6897

C'est tout à fait possible. Mais comme tout le monde le souligne, je n'infligerais jamais cela à un vrai projet.

Ma réponse, si vous êtes curieux, est ici . J'ai essayé de l'écrire en perl, mais il ne supporte pas les lookbehinds de longueur variable.

EDIT : Corrigé ! Le code lié fonctionne maintenant. Si vous voulez des conseils, il suffit de commenter - je ne veux pas vous donner le code si vous voulez le résoudre vous-même.

1voto

Alan Moore Points 39365

Pas dans une seule regex. Vous devez faire deux passages : matches() pour trouver le plus long préfixe commun, puis replaceAll() pour l'enlever. Voici ma meilleure solution :

import java.util.regex.*;

public class Test
{
  public static void main(String[] args) throws Exception 
  {
    String target = 
        "\t\tif(editorPart instanceof ITextEditor){\n"
      + "\t\t\tITextEditor editor = (ITextEditor)editorPart;\n"
      + "\t\t\tselection = (ITextSelection) fee.fie().fum();\n"
      + "\t\t}else if( editorPart instanceof MultiPageEditorPart){\n"
      + "\t\t\t//this would be the case for the XML editor\n"
      + "\t\t\tselection = (ITextSelection) fee.fie().foe().fum();\n"
      + "\t\t}";
    System.out.printf("%n%s%n", target);

    Pattern p = Pattern.compile("^(\\s+).*+(?:\n\\1.*+)*+");
    Matcher m = p.matcher(target);
    if (m.matches())
    {
      String indent = m.group(1);
      String result = target.replaceAll("(?m)^" + indent, "");
      System.out.printf("%n%s%n", result);
    }
  }
}

Bien entendu, cela suppose (comme Jonathan Leffler l'a laissé entendre dans son commentaire à votre question) que la chaîne cible ne fait pas partie d'une chaîne plus large et que vous ne supprimez que les espaces. Sans ces hypothèses, la tâche devient beaucoup plus complexe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X