【问题标题】:Replace an Expression Within Text Boundaries替换文本边界内的表达式
【发布时间】:2010-10-23 23:26:31
【问题描述】:

我有一个相当烦人的问题,我使用 Java 中的一个简单递归方法解决了这个问题。不过,我正在寻找更好的方法来做到这一点。

最初的问题涉及在 Quoted Printable/Base64 编码的 Mime 标头中存在空白 - 当我阅读 RFC 2047 规范时 - 这是不允许的。这意味着当出现空白时,MIME 标头的解码失败,例如

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

或更贴切地:

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

我们的目标是只删除 =? 之间的空格。 ?= 边界(或使用 =20 重新编码)。应保留此之外的其他文本。

我正在寻找解决此问题的替代方法,我的目标语言是 Java。关于最简单、最干净的方法的任何想法?

【问题讨论】:

    标签: java email text mime replace


    【解决方案1】:

    正则表达式http://java.sun.com/docs/books/tutorial/essential/regex/

    \s = 空格
    \S = 非空白
    \? = 转义问号
    . = 所有字符,类似于较弱模式匹配中的 *。

    使用这样的方法进行多部分查找和替换可能是最简单的: 拉出这部分:=\?.\?=

    将该部分中的 \s 全局替换为空字符串。

    把零件放回去。

    如果您使用正则表达式的时间足够长,您也许可以将其归结为一次搜索和替换...

    【讨论】:

    • 您可以使用捕获组并迭代结果,但此时您可能最好使用简单的递归方法,我认为它本质上是 pgras 的状态机。
    【解决方案2】:

    您可以构建一个简单的状态机来跟踪您是否介于 =?和 ?= ,然后按字符读取输入字符并在需要时通过字符转换空格输出它...

    【讨论】:

      【解决方案3】:

      您可以将字符串拆分为 ?,然后将其重新组合在一起,在替换空格和不替换空格之间交替。

      编辑:糟糕。错过了等号。会更正。

      编辑 2:更正的实现(源自 Matcher.appendReplacement() 的 Javadoc 示例):

      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());
      

      【讨论】:

      • =?iso-8859-1?Q?H=E4 ll?= 在这种情况下呢? :) =?iso-8859-1?Q?mon nk ey?=
      【解决方案4】:

      嗯,我不知道更好,但这里有另一种方法:

          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();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-11
        • 1970-01-01
        • 2011-03-28
        • 1970-01-01
        相关资源
        最近更新 更多