欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java将UBB转换为HTML实现,javaubb转换html,UBB2HTML 是一个

来源: javaer 分享于  点击 8973 次 点评:96

Java将UBB转换为HTML实现,javaubb转换html,UBB2HTML 是一个


UBB2HTML 是一个用来将 UBB 码转换成 HTML 代码的 Java 类库。

使用方法:

String html = UBBDecoder.decode("[b]I Love You[/b]");

实现类 UBBDecoder.java

/** *  */package com.dlog4j.util;import java.util.*;/** * UBB解码类 * @author liudong */public class UBBDecoder {    public static final int MODE_IGNORE = 0;    public static final int MODE_CLOSE = 1;    private static final int SEARCH_LEN = 200;    /**     * 进行UBB标签的转换     * @param s 需要转换的包含UBB标签的文本     * @param th 用户自定义的UBB标签的处理器的实例     * @param mode 容错模式,可以是忽略模式(MODE_IGNORE)或关闭模式(MODE_CLOSE)     * @return 转换后的包含HTML标签的文本     */    public static final String decode(String s, UBBTagHandler th, int mode) {        return decode(s, th, mode, false);    }    public static final String decode(String s) {        return UBBDecoder.decode(s, new SimpleTagHandler(),                UBBDecoder.MODE_CLOSE);    }    /**     * 进行UBB标签的转换     * @param s 需要转换的包含UBB标签的文本     * @param th 用户自定义的UBB标签的处理器的实例     * @param mode 容错模式,可以是忽略模式(MODE_IGNORE)或关闭模式(MODE_CLOSE)     * @param convBr 是否把'\n'字符也转换为'<br>'     * @return 转换后的包含HTML标签的文本     */    public static final String decode(String s, UBBTagHandler th, int mode,            boolean convBr) {        StringBuffer buf = new StringBuffer(); // 当前文本        char[] cc = s.toCharArray(); // 把输入转换为字符数组以提高处理性能        int len = cc.length, pos = 0;        UBBNode root = new UBBNode(null, "", null, "", false); // 根节点        UBBNode node = root; // 当前节点        Stack<UBBNode> stk = new Stack<UBBNode>(); // 使用堆栈处理节点的嵌套        stk.push(node);        while (pos < len) { // 只要未到文件末尾就循环            char cur = cc[pos]; // 当前字符            if (convBr && cur == '\n') { // 如果当前字符是换行                buf.append("\n<br />");                pos++;                continue;            }            if (convBr && cur == '\t') { // 如果当前字符是制表符                buf.append("    ");                pos++;                continue;            }            if (convBr && cur == ' ') { // 如果当前字符是空字符                buf.append(" ");                pos++;                continue;            }            if (cur != '[') { // 只要当前字符不是'['就扩展到当前文本                buf.append(cur);                pos++;                continue;            }            // 如果当前字符是'[',那么查找下一个']'            int ii = indexOf(cc, ']', pos + 1, SEARCH_LEN);            if (ii == -1) { // 未找到,把当前'['作为一般字符处理,扩展到当前文本                buf.append(cur);                pos++;                continue;            }            if (cc[pos + 1] == '/') { // 标签以'/'起始,可能是结束标签                if (cc[pos + 2] == ']') { // 修正littlebat发现的bug,处理"[/]"的情况                    buf.append("[/]");                    pos += 3;                    continue;                }                // 得到结束标签的文本                String tmp = new String(cc, pos + 2, ii - pos - 2).trim()                        .toLowerCase();                int cnt = 1;                boolean find = false;                // 在节点树上向上查找和本结束标签对应的标签                for (UBBNode nd = node; nd != null; nd = nd.parent, cnt++) {                    if (nd.tag.equals(tmp)) {                        find = true;                        break;                    }                }                if (find) { // 如果在节点树上找到了和本结束标签对应的标签                    // 先把当前文本扩展到当前节点                    addTextChild(node, buf);                    // 从堆栈中弹出节点,直到找到的标签成为当前节点                    while (cnt-- > 0) {                        // 对于CLOSE容错模式,把当前节点和找到的标签节点之间的标签全部关闭                        if (mode == MODE_CLOSE) {                            node.closed = true;                        }                        node = (UBBNode) stk.pop();                    }                    // 关闭当前标签节点,当前节点上移一层                    node.closed = true;                    node = node.parent;                    pos = ii + 1;                    continue;                } else { // 未找到对应起始标签,作为普通文本处理                    buf.append("[/");                    pos += 2;                    continue;                }            } else if (cc[ii - 1] == '/') { // 标签以'/'结尾,可能是空标签                String tmp = new String(cc, pos + 1, ii - pos - 2).trim();                // 由UBBTagHandler决定是否是一个合法空标签                String[] ss = th.parseTag(tmp, true);                if (ss != null && ss.length == 3) { // 处理空标签                    // 先把当前文本扩展到当前节点                    addTextChild(node, buf);                    UBBNode nd = new UBBNode(node, ss[0].toLowerCase(), ss[1]                            .split(","), new String(cc, pos, ii + 1 - pos),                            true);                    node.addChild(nd);                    pos = ii + 1;                    continue;                }            }            // 可能是普通起始标签            // 得到标签文本            String tmp = new String(cc, pos + 1, ii - pos - 1).trim();            // 由UBBTagHandler决定是否是合法标签            String[] ss = th.parseTag(tmp, false);            if (ss != null && ss.length == 2) { // 是合法标签                // 先把当前文本扩展到当前节点                addTextChild(node, buf);                // 创建新的节点,扩展到当前节点,然后当前节点下移一层                UBBNode nd = new UBBNode(node, ss[0].toLowerCase(), ss[1]                        .split(","), new String(cc, pos, ii + 1 - pos), false);                node.addChild(nd);                pos = ii + 1;                stk.push(nd);                node = nd;            } else { // 不是标签,当作普通文本处理                buf.append('[');                pos++;            }        }        // 把当前文本中剩余的内容扩展到当前节点        addTextChild(node, buf);        //System.out.println("=========================\n" + root.toString(0));        // 使用节点树构造输出文本        String show = decodeNode(th, root);        show = show.replaceAll("\\[br\\]", "\n<br />");        return show.replaceAll("\\[em:(.+?)\\]","<img src='/image/emote/em$1.gif' style=\"border:0\">");    }    /**     * 把文本生成一个纯文本节点并扩展到给定的节点     * @param node     * @param buf     */    private static void addTextChild(UBBNode node, StringBuffer buf) {        if (buf.length() > 0) {            node.addChild(new UBBNode(node, buf.toString()));            buf.setLength(0);        }    }    /**     * 从标签节点树来递归的构造输出文本     * @param th     * @param node     * @return     */    private static String decodeNode(UBBTagHandler th, UBBNode node) {        StringBuffer buf = new StringBuffer(); // 输出文本        if (UBBNode.TEXT == node.tag) {            // 处理纯文本节点            buf.append(node.img);        } else if (!node.closed) {            // 处理未正常关闭的节点,节点本身当作纯文本处理,对其子节点进行递归处理            buf.append(node.img);            List<UBBNode> lst = node.children;            if (lst != null && lst.size() > 0) {                for (int i = 0, n = lst.size(); i < n; i++) {                    buf.append(decodeNode(th, (UBBNode) lst.get(i)));                }            }        } else {            // 处理正常节点,使用UBBTagHandler来组合输出,并递归处理其子节点            List<UBBNode> lst = node.children;            StringBuffer tmp = new StringBuffer();            if (lst != null && lst.size() > 0) {                for (int i = 0, n = lst.size(); i < n; i++) {                    tmp.append(decodeNode(th, (UBBNode) lst.get(i)));                }            }            buf.append(th.compose(node.tag, node.attr, tmp.toString(),                    node.isEmpty));        }        return buf.toString();    }    private static final int indexOf(char[] cc, char c, int idx, int len) {        int end = idx + len;        if (end > cc.length)            end = cc.length;        for (int i = idx; i < end; i++) {            if (cc[i] == c) {                return i;            }        }        return -1;    }}class UBBNode {    static final String TEXT = "<text>";    String tag = null;    String[] attr = null;    String img = null;    UBBNode parent = null;    List<UBBNode> children = null;    boolean closed = false;    boolean isEmpty = false;    UBBNode(UBBNode parent, String tag, String[] attr, String img,            boolean isEmpty) {        this.parent = parent;        this.tag = tag.toLowerCase();        this.attr = attr;        this.img = img;        this.isEmpty = isEmpty;        this.closed = isEmpty;        this.children = isEmpty ? null : new ArrayList<UBBNode>();    }    UBBNode(UBBNode parent, String text) {        String[] text1 = { text };        this.parent = parent;        this.tag = TEXT;        this.attr = text1;        this.img = text;        this.closed = true;        this.isEmpty = true;    }    final void addChild(UBBNode child) {        children.add(child);    }    /**     *      */    public final String toString() {        return "[tag=\"" + tag + "\",attr=\"" + attr + "\",closed=" + closed                + ",children="                + (children != null ? "" + children.size() : "null") + "]";    }    /**     *     * @param i     * @return     */    final String toString(int i) {        StringBuffer buf = new StringBuffer();        for (int j = i; --j >= 0;) {            buf.append(' ');        }        buf.append(toString() + "\n");        if (children != null && children.size() > 0) {            for (int j = 0, n = children.size(); j < n; j++) {                buf.append(((UBBNode) children.get(j)).toString(i + 2));            }        }        return buf.toString();    }}class SimpleTagHandler implements UBBTagHandler {    //    [b]文字加粗体效果[/b]    //    [i]文字加倾斜效果[/i]    //    [u]文字加下划线效果[/u]    //    [size=4]改变文字大小[/size]    //    [color=red]改变文字颜色[/color]    //    [quote]这个标签是用来做为引用所设置的,如果你有什么内容是引用自别的地方,请加上这个标签![/quote]      //    [url]http://www.cnjm.net[/url]    //    [url=http://www.cnjm.net]JAVA手机网[/url]    //    [email=webmaster@cnjm.net]写信给我[/email]     //    [email]webmaster@cnjm.net[/email]    //    [img]http://www.cnjm.net/myimages/mainlogo.gif[/img]    public SimpleTagHandler() { }    public String[] parseTag(String s, boolean isEmpty) {        if (isEmpty) { // 本处理器不支持空标签            return null;        }        // 如果标签中有'='号就把标签分为UBB标记和属性两部分,否则属性为空        String tag = s, attr = "";        int idx = s.indexOf('=');        if (idx >= 0) {            tag = s.substring(0, idx);            attr = s.substring(idx + 1);        } else {            idx = s.indexOf(':');            if (idx >= 0) {                tag = s.substring(0, idx);                attr = s.substring(idx + 1);            }        }        String tmp = tag.toLowerCase(); // 大小写不敏感        // 只有下面的标记是本处理器支持的        if ("b".equals(tmp) || "i".equals(tmp) || "u".equals(tmp)                || "size".equals(tmp) || "color".equals(tmp)                || "quote".equals(tmp) || "url".equals(tmp)                || "email".equals(tmp) || "img".equals(tmp) || "*".equals(tmp)                || "list".equals(tmp) || "fly".equals(tmp)                || "move".equals(tmp) || "align".equals(tmp)                || "flash".equals(tmp) || "wmv".equals(tmp) || "rm".equals(tmp)                || "code".equals(tmp) || "glow".equals(tmp)                || "sign".equals(tmp) || "em".equals(tmp)) {            return new String[] { tag, attr };        }        // 不是一个合法的UBB标签,作为普通文本处理        return null;    }    public String compose(String tag, String[] attr, String data,            boolean isEmpty) {        // 针对不同标记进行组合工作        String tmp = tag;        String style = null;        if ("b".equals(tmp) || "i".equals(tmp) || "u".equals(tmp)) {            return "<" + tag + ">" + data + "</" + tag + ">";        } else if ("size".equals(tmp) || "color".equals(tmp)) {            return "<font " + tag + "='" + attr[0] + "'>" + data + "</font>";        } else if ("quote".equals(tmp)) {            return "<div class=\"clearfix\"> </div><div class='quote'><div class='fheader_fillet'><div class='fheader_fillet1'><div class='fheader_fillet2'></div></div></div><div class='quotemain'><div class='quotemain1'><div class='quotemain2'>"                    + data                    + "</div></div></div><div class='ffooter_fillet'><div class='ffooter_fillet1'><div class='ffooter_fillet2'></div></div></div></div>";        } else if ("url".equals(tmp)) {            String link = attr[0] != "" ? attr[0] : data;            String domain;            link.trim();            String code = link.substring(0, 1);            if (code.equals("#") == true) {                return "<a href='" + link + "'>" + data + "</a>";            } else {                int index = link.indexOf('/');                if (index < 0) {                    link = "http://" + link;                } else {                    String head = link.substring(0, index);                    if ((head.equals("http:") == false)                            && (head.equals("ftp:") == false)                            && (head.equals("gopher:") == false)                            && (head.equals("news:") == false)                            && (head.equals("telnet:") == false)                            && (head.equals("mms:") == false)                            && (head.equals("rtsp:") == false))                        link = "http://" + link;                }                try {                    domain = link.substring((link.indexOf('.') + 1));                    domain = domain.substring(0, (domain.indexOf('.')));                } catch (Exception ex) {                    domain = "";                }                if (domain.equals("moabc"))                    return "<a href='" + link + "' target=_blank>" + data+ "</a>";                else                    return "<a href='/wap/out?url="+ link + "' target=_blank>" + data + "</a>";            }        } else if ("email".equals(tmp)) {            String email = attr[0] != "" ? attr[0] : data;            return "<a href='mailto:" + email + "'>" + data + "</a>";        } else if ("img".equals(tmp)) {            return "<img src='" + data + "' border=0>";        } else if ("*".equals(tmp)) {            return "<li>" + data + "</li>";        } else if ("list".equals(tmp)) {            return "<ul>" + data + "</ul>";        } else if ("fly".equals(tmp)) {            return "<marquee width=90% behavior=alternate scrollamount=3>"                    + data + "</marquee>";        } else if ("move".equals(tmp)) {            return "<marquee scrollamount=3>" + data + "</marquee>";        } else if ("align".equals(tmp)) {            style = attr[0] != "" ? attr[0] : "left";            return "<div align='" + style + "'>" + data + "</div>";        } else if ("sign".equals(tmp)) {            return "<a name='" + attr[0] + "'>" + data + "</a>";        } else if ("flash".equals(tmp)) {            String height;            String width;            try {                height = attr[1];                width = attr[0];            } catch (Exception ex) {                height = String.valueOf(360);                width = String.valueOf(480);            }            return "<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" WIDTH="                    + width                    + " HEIGHT="                    + height                    + "><PARAM NAME=MOVIE VALUE='"                    + data                    + "'><PARAM NAME=PLAY VALUE=TRUE><PARAM NAME=LOOP VALUE=TRUE><PARAM NAME=QUALITY VALUE=HIGH><EMBED SRC='"                    + data                    + "' WIDTH="                    + width                    + " HEIGHT="                    + height                    + " PLAY=TRUE LOOP=TRUE QUALITY=HIGH></EMBED></OBJECT><br />[<a target=_blank href='"                    + data + "'>全屏播放</a>]";        } else if ("wmv".equals(tmp)) {            return "<EMBED src='" + data                    + "' HEIGHT=\"256\" WIDTH=\"314\" AutoStart=1></EMBED>";        } else if ("rm".equals(tmp)) {            return "<object classid=clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA height=241 id=Player width=316 VIEWASTEXT><param name=\"_ExtentX\" value=\"12726\"><param name=\"_ExtentY\" value=\"8520\"><param name=\"AUTOSTART\" value=\"0\"><param name=\"SHUFFLE\" value=\"0\"><param name=\"PREFETCH\" value=\"0\"><param name=\"NOLABELS\" value=\"0\"><param name=\"CONTROLS\" value=\"ImageWindow\"><param name=\"CONSOLE\" value=\"_master\"><param name=\"LOOP\" value=\"0\"><param name=\"NUMLOOP\" value=\"0\"><param name=\"CENTER\" value=\"0\"><param name=\"MAINTAINASPECT\" value=\""                    + data                    + "\"><param name=\"BACKGROUNDCOLOR\" value=\"#000000\"></object><br /><object classid=clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA height=32 id=Player width=316 VIEWASTEXT><param name=\"_ExtentX\" value=\"18256\"><param name=\"_ExtentY\" value=\"794\"><param name=\"AUTOSTART\" value=\"1\"><param name=\"SHUFFLE\" value=\"0\"><param name=\"PREFETCH\" value=\"0\"><param name=\"NOLABELS\" value=\"0\"><param name=\"CONTROLS\" value=\"controlpanel\"><param name=\"CONSOLE\" value=\"_master\"><param name=\"LOOP\" value=\"0\"><param name=\"NUMLOOP\" value=\"0\"><param name=\"CENTER\" value=\"0\"><param name=\"MAINTAINASPECT\" value=\"0\"><param name=\"BACKGROUNDCOLOR\" value=\"#000000\"><param name=\"SRC\" value=\""                    + data + "\"></object>";        } else if ("em".equals(tmp)) {            style = attr[0] != "" ? attr[0] : "1";            return "<img src='../ico/em" + attr[0]                    + ".gif' style=\"border:0\" >";        } else if ("glow".equals(tmp)) {            String glowwidth, glowcolor, glowstrength;            try {                glowwidth = attr[0];            } catch (Exception ex) {                glowwidth = String.valueOf(360);            }            try {                glowcolor = attr[1];            } catch (Exception ex) {                glowcolor = String.valueOf(360);            }            try {                glowstrength = attr[2];            } catch (Exception ex) {                glowstrength = String.valueOf(360);            }            return "<span style='WIDTH:" + glowwidth + ";filter:glow(color="                    + glowcolor + ", strength=" + glowstrength + ")'>" + data                    + "</span>";        } else if ("code".equals(tmp)) {            java.util.Random random = new java.util.Random();            int x = random.nextInt(9999);            String s = String.valueOf(x);            //System.out.println("data: \n" + data);            //int index = link.indexOf('/');            return "<div class=\"clearfix\"> </div><div class=\"somecode\"><div class=\"somecode_main\"><div class=\"fheader_fillet\"><div class=\"fheader_fillet1\"><div class=\"fheader_fillet2\"></div></div></div><div class=\"body\"><div class=\"code_header\"><input type=\"button\" value=\"复制代码\" onclick=\"getcode('code-content"                    + s                    + "')\" class=\"btn\"/></div><div class=\"code_tools\"><a class=\"c_to\" id=\"c_to"                    + s                    + "\" onclick=\"showsomecode('"                    + s                    + "')\"> </a></div><div class=\"code-content\" id=\"code-content"                    + s                    + "\">"                    + data                    + "</div><div id=\"code_footer"                    + s                    + "\"><div class=\"code_footer\"><input type=\"button\" value=\"复制代码\" onclick=\"getcode('code-content"                    + s                    + "')\" class=\"btn\"/></div><div class=\"code_tools\"><a class=\"c_to\" id=\"c_to\" onclick=\"showsomecode('"                    + s                    + "')\"> </a></div></div></div><!-- body --><div class=\"ffooter_fillet\"><div class=\"ffooter_fillet1\"><div class=\"ffooter_fillet2\"></div></div></div></div><!-- somecode_main --><div class=\"clearfix\"> </div></div>";        }        return data;    }    // 测试代码,可以运行这个类,并把包含UBB标签的文本作为参数传入来测试    // 比如java util.SimpleTagHandler "[color=red]你[color=blue]好[/color]啊[/color]"    public static void main(String[] args) throws Exception {        String ubb = "[color=red]你[color=blue]好[/color]啊  &&& [color=red]你<font color='blue'>好</font>啊";        System.out.println(">>>>" + ubb);        // 下面采用了忽略模式来容错,你也可以用MODE_CLOSE试验一下关闭模式的容错效果        System.out.println("=========================\n"                + UBBDecoder.decode(ubb, new SimpleTagHandler(),                        UBBDecoder.MODE_CLOSE));    }}

UBBTagHandler.java

package com.dlog4j.util;public interface UBBTagHandler {    /**     * 解析一个可能的UBB标签(扩在[]之间的内容),如果是一个合法的UBB标签,则实现方法     * 要负责把传入的potentialTag解析成标签符号(tag)和属性(attribute)两部分,并作为     * 一个字符串数组传回,如果potentialTag并非一个合法的UBB标签,则应返回null。     * 注意'['和']'是不会作为potentialTag的一部分传给本方法的。     * @param potentialTag      * @param isEmpty 是否是一个空标签,即形式为[.../],没有内层嵌套文本的UBB标签     * @return 如果输入是合法UBB标签,则返回经解析后的的标签符号和相应属性,否则返回null     */    public String[] parseTag(String potentialTag, boolean isEmpty);    /**     * 把给定的UBB标签转换组合成输出形式     * @param tag 标签符号     * @param attr 标签属性     * @param data 标签中的内容(已经转换成输出形式后的)     * @param isEmpty 是否是一个空标签,即形式为[.../],没有子标签的UBB标签     * @return 组合好的字符串     */    public String compose(String tag, String[] attr, String data, boolean isEmpty);}
相关栏目:

用户点评