使用Java StringBuilder的正则表达式

时间:2019-01-30 05:42:38

标签: java regex stringbuilder

当我执行该程序时,它运行正常

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    public class RegexMatches {

       public static void main( String args[] ) {
          // String to be scanned to find the pattern.
          String line = "0X10001,0X10002,0X610001,0X610002";
          String pattern = "0X(?=\\d{6})|(0)X(?=\\d{5})";

          // Create a Pattern object
          Pattern r = Pattern.compile(pattern);

          // Now create matcher object.
          Matcher m = r.matcher(line);
          StringBuffer builder = new StringBuffer(); 
          while (m.find()) { 
                m.appendReplacement(builder, 
                                          "$1"); 
            } 
            m.appendTail(builder); 

            // Print the replaced matcher 
            System.out.println("After Replacement: "
                               + builder.toString()); 
        } 
       }

但是当我在下面的代码中包含相同的代码段时,会引发错误。 (此代码将rawData写入CSV文件,但在写入之前进行十六进制清除。)

public static String writeToCSV(StringBuilder rawData, String granularity, String threadName, long collectionTime)
      throws IOException {
    StringBuilder fileName = new StringBuilder();
    fileName.append(String.valueOf(System.currentTimeMillis())).append("_").append(threadName).append(".csv");
    StringBuilder directoryPath = new StringBuilder();
    directoryPath.append(TEMP_DATA_DIR_PATH).append(granularity).append(File.separator).append(collectionTime);
    AmpStatsDataUtil.createWritableDirectory(directoryPath.toString());
    StringBuilder filePath = new StringBuilder();
    filePath.append(directoryPath.toString()).append(File.separator).append(fileName.toString());
    BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(new FileOutputStream(filePath.toString(), true), "UTF-8"));

    // Hexadecimal clean up
    Pattern r = Pattern.compile("0x(?=\\d{6})|(0)x(?=\\d{5})");
    Matcher m = r.matcher(rawData);
    StringBuffer builder = new StringBuffer(); 
     while (m.find()) { 
            m.appendReplacement(builder,"$1"); 
        } 
        m.appendTail(builder);
        LOGGER.info("Cleaned hexadecimal digits are {0}",builder.toString());
    try {
      bw.write(builder.toString());
    } catch (IOException e) {
      LOGGER.error("Error while writing data to CSV file:{0}", e);
    } finally {
      try {
        if (bw != null) {
          bw.flush();
        }
        bw.close();
      } catch (IOException e) {
        LOGGER.error("Error while closing bufferedwriter:{0}", e);
      }
    }
    return fileName.toString();
  }

但是不使用字符串生成器就可以正常工作:

//code 3
public static String writeToCSV(StringBuilder rawData, String granularity, String threadName, long collectionTime)
      throws IOException {
    StringBuilder fileName = new StringBuilder();
    fileName.append(String.valueOf(System.currentTimeMillis())).append("_").append(threadName).append(".csv");
    StringBuilder directoryPath = new StringBuilder();
    directoryPath.append(TEMP_DATA_DIR_PATH).append(granularity).append(File.separator).append(collectionTime);
    AmpStatsDataUtil.createWritableDirectory(directoryPath.toString());
    StringBuilder filePath = new StringBuilder();
    filePath.append(directoryPath.toString()).append(File.separator).append(fileName.toString());
    BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(new FileOutputStream(filePath.toString(), true), "UTF-8"));

    // Hexadecimal clean up
    Pattern myPattern = Pattern.compile("0x");
    Matcher myMatcher = myPattern.matcher(rawData);
    try {
      bw.write(myMatcher.repalaceAll("0");
    } catch (IOException e) {
      LOGGER.error("Error while writing data to CSV file:{0}", e);
    } finally {
      try {
        if (bw != null) {
          bw.flush();
        }
        bw.close();
      } catch (IOException e) {
        LOGGER.error("Error while closing bufferedwriter:{0}", e);
      }
    }
    return fileName.toString();
  }

您能告诉我为什么第二段代码不能编译吗?

1 个答案:

答案 0 :(得分:0)

Javadoc for Matcher,我们可以看到appendReplacementappendTail方法仅使用StringBuffer

public Matcher appendReplacement(StringBuffer sb, String replacement)
public StringBuffer appendTail(StringBuffer sb)

因此,如果要编译它,则需要使用StringBuffer版本。