Extract Text from BBCode String

正如其名字所暗示的,BBCode 广泛用在论坛程序开发中,比如 phpbbvbb 等。存储在数据库中的字符串往往是混杂 BBCode 的,如何从这些字符串中剔除 BBCode,以提取纯文本信息?如果使用 PHP 语言,有很多现成可用的 PHP BBCode parser。但如果使用 Java 呢?似乎很难找到现成的 Java BBCode parser。当然,可以使用正则表达式来做匹配分析,不过失之繁琐。无意中,在 JBoss Portal v2.6.7 中发现了一个组件可以分析 BBCode,位于 org.jboss.portal.format.* 包中,其 jar 文件是 portal-format-lib.jar

使用方法:

ToTextRenderer render = new ToTextRenderer();
StringWriter writer = new StringWriter();
render.setWriter(writer);
render.render(bbString.toCharArray(), 0, bbString.length());
String txt = writer.toString();

就是这么简单。

不过这个 JBoss Portal format 组件只支持小写的 BBCode,比如 [b] [/b],不支持大写的,比如 [B] [/B]。
可以修改源码包 org.jboss.portal.format.parser.bbcode 中的 Analyzer.flex 来实现对大写的支持:(以下大写均为我所添加)

<YYINITIAL>
{
"[b]" | "[B]" { return token(OPEN_B, null); }
"[/b]" | "[/B]" { return token(CLOSE_B, null); }
"[i]" | "[I]" { return token(OPEN_I, null); }
"[/i]" | "[/I]" { return token(CLOSE_I, null); }
"[u]" | "[U]" { return token(OPEN_U, null); }
"[/u]" | "[/U]" { return token(CLOSE_U, null); }
"[color="(([A-Za-z]+)|("#"[0-9A-Fa-f]{6}))"]" { return token(OPEN_COLOR, yytext().substring(7, yytext().length() - 1)); }
"[COLOR="(([A-Za-z]+)|("#"[0-9A-Fa-f]{6}))"]" { return token(OPEN_COLOR, yytext().substring(7, yytext().length() - 1)); }
"[/color]" | "[/COLOR]" { return token(CLOSE_COLOR, null); }
"[size="[0-9]{1,2}"]" { return token(OPEN_SIZE, yytext().substring(6, yytext().length() - 1)); }
"[SIZE="[0-9]{1,2}"]" { return token(OPEN_SIZE, yytext().substring(6, yytext().length() - 1)); }
"[/size]" | "[/SIZE]" { return token(CLOSE_SIZE, null); }
"[quote]" | "[QUOTE]" | "[Quote]" { return token(OPEN_QUOTE_ANONYMOUS, null); }
"[quote="~["]"] { return token(OPEN_QUOTE, yytext().substring(7, yytext().length() - 1)); }
"[QUOTE="~["]"] { return token(OPEN_QUOTE, yytext().substring(7, yytext().length() - 1)); }
"[Quote="~["]"] { return token(OPEN_QUOTE, yytext().substring(7, yytext().length() - 1)); }
"[/quote]" | "[/QUOTE]" | "[/Quote]" { return token(CLOSE_QUOTE, null); }
"[code]" | "[CODE]" | "[Code]" { return token(OPEN_CODE, null); }
"[/code]" | "[/CODE]" | "[/Code]" { return token(CLOSE_CODE, null); }
"[list]" | "[LIST]" | "[List]" { return token(OPEN_LIST_UNORDERED, null); }
"[list=1]" | "[LIST=1]" | "[List=1]" { return token(OPEN_LIST_ORDERED_NUMERICAL, null); }
"[list=a]" | "[LIST=a]" | "[List=a]" { return token(OPEN_LIST_ORDERED_ALPHABETICAL, null); }
"[/list]" | "[/LIST]" | "[/List]" { return token(CLOSE_LIST, null); }
"[*]" { return token(LIST_ITEM, null); }
"[url"~["]"]~["["]"/url]" { return token(LINK, yytext().substring(4, yytext().length() - 6)); }
"[URL"~["]"]~["["]"/URL]" { return token(LINK, yytext().substring(4, yytext().length() - 6)); }
.|\n { return token(TEXT, yytext()); }
}

使用 JFlex 来生成对应的 Analyzer.java 文件,然后将编译好的 Analyzer.class 放到 portal-format-lib.jar 中替换原先的 class。

另外一个问题是,不支持用户自定义的 BBCode。我还没有找到简单易行的解决方案,以后再想吧。

[UPDATE] 3 Mar 2010
这篇文章已过时,有更好的方法

This entry was posted in Development and tagged . Bookmark the permalink.

One Response to Extract Text from BBCode String

  1. Pingback: Use KefirBB to Extract Text from BBCode String | 细柳营

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">