最近在工作当中经常遇到需要进行文本文件处理的一些工作,尤其是一些文本的翻译。这里的翻译是指,将其中的文本,一整行或是多行翻译成对应语言的文本,当然有对应的字典库。举个例子
 

 
    
  1. ……  
  2. insert into WbxDefaultEmailTemplate(EMAILNAME,LOCALE,SERVICEID,MAILFORMAT,MAILTYPE,RELEASENAME,BLOCKID,PRODUCTTYPE,SUBJECT,MESSAGE)  
  3. VALUES('Absentee Followup','en_US',6,0,0,:v_release_name,0,'','We missed you at the Web seminar: %Topic%',  
  4. 'Hello %AttendeeName%,  
  5.  
  6. We missed you at the Web seminar %Topic% on %MeetingDate%.  
  7.  
  8. If you have comments or questions, contact the seminar host, %HostName%, at:  
  9. %HostEmail%  
  10.  
  11. %EmailFooter%  
  12. ');  
  13.  
  14. insert into WbxDefaultEmailTemplate(EMAILNAME,LOCALE,SERVICEID,MAILFORMAT,MAILTYPE,RELEASENAME,BLOCKID,PRODUCTTYPE,SUBJECT,MESSAGE)  
  15. VALUES('Absentee Followup','en_US',6,1,0,:v_release_name,0,'','We missed you at the Web seminar: %Topic%',  
  16. '%DefaultHeaderImage%<table width="576" border="0" cellpadding="0" cellspacing="0">  
  17. size="2" face="Tahoma, Arial, sans-serif, Helvetica, Geneva">
     
  18. Hello %AttendeeName%,
     

  19.  
  20. We missed you at the Web seminar %Topic% on %MeetingDate%.
     

  21.  
  22. If you have comments or questions, contact the seminar host, %HostName%, at:
     
  23. %HostEmail%
     

  24.  
  25. %EmailFooter%
     
  26. table>%DefaultFooterImage%  
  27. ');  
  28. …… 

这是一个SQL文件,需要将其中的每一行提取出来之后在字典库中找出对应语言的翻译,然后再替换文本。如果按照逐行文本进行读取到没有什么可说,只是这里还要从文本中提取一些标识作为“Unique”标志,也就是一次多义的处理。比如第一个insert语句中的EMAILNAME和SERVICEID的值。

在提取这些值的时候,如果按行为单位读取然后再去解析出这些标识的值显然比较繁琐且效率不高,那么如果直接使用正则表达式的话,对于多行文本的匹配又很容易出错,那么如何处理才是恰当的呢?这里给出一种我在实际处理过程中的解决方案。
首先,需要对这里给出的文本进行封装,这里给出的SQL文件其实是结构化的文本,有多个有完整语义的SQL语句组成。可以将每个完整的SQL语句作为一个unit封装到一个对象中。
其次,在进行标识值提取的时候,可以将多行文本读取到一个StringBuffer中,去掉换行符。那么StringBuffer中的内容就变成了单行文本,然后再使用写好的正则进行匹配提取。
另外,还需要在封装的对象中保留一份包含原有文本格式(尤其是包含换行符)的文本,以便于提取单行文本的时候更加方便。

通过这种方式,既可以方便的提取标识值又可以在提取当行文本的时候避免重复的读取文件。依次类比,其他格式的结构化文本,尤其是自定义的结构化文本的处理,也可以从中得到一些启发。