2009-05-05 12 views
4

J'ai un problème plutôt ennuyeux que j'ai résolu en utilisant une méthode récursive simple en Java. Cependant, je cherche une meilleure façon de le faire.Remplacer une expression dans les limites de texte

Le problème initial impliquait la présence d'espaces dans un en-tête MIME codé imprimable/Base64 - qui, selon la spécification RFC 2047, n'est pas autorisé. Cela signifie que le décodage échoue pour un en-tête MIME lorsqu'un espace blanc est présent, par ex.

=?iso-8859-1?Q?H=E4 ll and nothing?= 

ou plus pertinemment:

=?iso-8859-1?Q?H=E4 ll?= preserve this text =?iso-8859-1?Q?mo nk ey?= 

L'objectif est de supprimer uniquement les espaces entre les =? ? = frontières (ou ré-encoder en utilisant = 20). L'autre texte en dehors de ceci devrait être préservé.

Je suis à la recherche d'approches alternatives pour résoudre cette langue cible pour Java. Des idées sur l'approche la plus simple et la plus propre à cela?

Répondre

2

Vous pouvez construire une simple machine d'état à suivre si vous êtes entre =? et? =, puis lisez le char en entrée par char et enregistrez le char par char convertissant les espaces lorsque nécessaire ...

0

Expressions régulières http://java.sun.com/docs/books/tutorial/essential/regex/.

\ s = espaces
\ S = non des espaces
\? = point d'interrogation échappé
. = tous les caractères, semblables à * en correspondance plus faible.

est peut-être plus facile à faire en plusieurs parties rechercher et remplacer en utilisant quelque chose comme ceci: Retirez cette partie:.? = \ \ =

Globalement remplacer \ s dans cette partie avec une chaîne vide.

Replacez la pièce.

Vous pourriez être en mesure de le faire descendre à une recherche unique et le remplacer si vous jouez avec la regex assez longtemps ...

+0

Vous pouvez utiliser des groupes de capture et parcourir les résultats, mais à ce stade, vous êtes probablement mieux avec votre méthode récursive simple qui, je suppose, est essentiellement la machine d'état de pgras. – steamer25

-1

Vous pouvez diviser la chaîne sur?, puis la remettre ensemble, en alternant le remplacement des espaces et non.

Editer: Oups. Manqué les signes égaux. Corrigera.

Edit 2: mise en œuvre corrigée (dérivé de l'exemple Javadoc pour Matcher.appendReplacement()):

String input = "=?iso-8859-1?Q?H=E4 ll?= what about in this case? :) =?iso-8859-1?Q?mo nk ey?="; 

Pattern p = Pattern.compile("=\\?(.*?)\\?="); 
Matcher m = p.matcher(input); 
StringBuffer sb = new StringBuffer(); 
while (m.find()) { 
    m.appendReplacement(sb, m.group().replaceAll(" ", "")); 
} 
m.appendTail(sb); 
System.out.println(sb.toString()); 
+0

=? Iso-8859-1? Q? H = E4 ll? = Qu'en est-il dans ce cas? :) =? iso-8859-1? Q? mo nk ey? = – Jon

0

Eh bien, je ne sais pas mieux, mais voici une autre approche:

public static void main(String[] args) 
    { 
     String ex1 = "=?iso-8859-1?Q?H=E4 ll?= " + 
      "preserve this text =?iso-8859-1?Q?mo nk ey?="; 
     String res1 = removeSpaces(ex1); 

     System.out.println(ex1); 
     System.out.println(); 
     System.out.println(res1); 
    } 

    public static String removeSpaces(String str) 
    { 
     StringBuffer result = new StringBuffer(); 
     String strPattern = "(\\?.+\\?)"; 
     Pattern p = Pattern.compile(strPattern); 
     Matcher m = p.matcher(str); 

     if (!m.find() || m.groupCount() == 0) 
     { // Contains no matching sequence. 
      return str; 
     } 

     for (int i = 1; i <= m.groupCount(); i++) 
     { 
      m.appendReplacement(result, 
       m.group(i).replaceAll("\\s", "")); 
     } 

     return result.toString(); 
    }