`
tangxiucai2
  • 浏览: 4073 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
社区版块
存档分类
最新评论

wiki文本处理引擎

 
阅读更多
package me.txc.idiom;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Wiki文字处理引擎
 * <p>
 * 常用wiki体列举如下:
 * <ol>
 * <li>直接闭合
 * <ul>
 * <li> ---- 对应 </hl> </li>
 * <li> > 对应 <ul> </li>
 * <li> >> 对应 <li> </li>
 * </ul>
 * </li>
 * <li>单值
 * <ul>
 * <li> [img[xxx.jpg]] 对应 </hr> </li>
 * <li> ``xxx`` 对应 <b> xxx </b></li>
 * <li> //xxx// 对应 <i> xxx </i></li>
 * </ul>
 * </li>
 * <li>多值
 * <ul>
 * <li> @@color(red):xxx@@ 对应 <font color="red"> xxx </font>
 * </li>
 * <li> @@bgcolor(red):xxx@@ 对应 <span background="red"> xxx
 * </span> </li>
 * </ul>
 * </li>
 * <li>特殊处理
 * <ul>
 * <li>表格</li>
 * <li>列表</li>
 * </ul>
 * </li>
 * </ol>
 * </p>
 * 
 * @author tangxiucai2@gmail.com
 * 
 */
public class WikiTextEngine {
	private final static int NONE_VALUE = 0;
	private final static int SINGLE_VALUE = 1;

	public static void main(String[] args) {
		WikiTextEngine wh = new WikiTextEngine();
		wh.addWikiText("``", "<b>$1</b>", "文字加粗", "", 1);
		wh.addWikiText("//", "<i>$1</i>", "文字倾斜", "", 1);
		wh.addWikiText("----", "<hr>", "横线", "", 0);
		wh.addWikiText("@@color()", "<font color=\"$1\"/>$2</font>", "文字颜色",
				"@@color\\((.+?)\\):(.+?)@@", 2);
		wh.addWikiText("@@bgcolor()", "<span background=\"$1\">$2</span>",
				"文本背景色", "@@bgcolor\\((.+?)\\):(.+?)@@", 2);
		wh.addWikiText("--", "删除", new WikiTextHandler(){
			@Override
			public String process(String target) {
				String regex = "--(.+?)--";
				if(Pattern.matches(regex, target)){
					Pattern pattern = Pattern.compile(regex);
					for(Matcher matcher = pattern.matcher(target); matcher.find();){
						String findStr = matcher.group();
						String includedStr = matcher.group(1);
						String newStr = "(已删除:" +includedStr+ ")";
						target = target.replaceAll(findStr, newStr);
					}
				}
				return target;
			}});

		String[] demo = new String[] { "abc----", "``hello``", "//he llo//",
				"@@color(blue):This is --some-- text.@@", "@@bgcolor(red):文本 背景.@@",
				"--xxx--yyy--zzz--" };

		for (String str : demo)
			System.out.println(wh.process(str));
	}

	/**
	 * 添加Wiki体
	 * 
	 * @param symbol
	 *            符号 起到键的作用,需要保持唯一
	 * @param text
	 *            替代的HTML文本,$1代表发现的剔除符号外的文本的占位符 例如 要将``xxx``最终替换为
	 *            <b>xxx</b>则这里的text设为<b>$1</b>,要将[img[xxx.jpg]]最终替换为<img
	 *            src="xxx.jpg"/>则这里的text需设为<img src="$1"/>
	 * @param meaning
	 *            符号表示的含义
	 * @param regex
	 *            符号匹配的正则,如果存在对应的正则,则按照设定的正则进行特殊匹配 例如 [img[(\\w+)]] 可以匹配
	 *            [img[xxx.jpg]];否则将默认按照首尾一致的原则进行匹配 例如 --(\\w+)--
	 *            但是所有组装出的正则中不应该在存在()
	 * @param valueCount
	 *            占位符个数:取值0/1/2/... 不可设为-1(-1表示自定义解析规则) 即例如
	 *            <hr/>为0个,<b>xx <b>为1,< font
	 *            color="$1">$2 </font>
	 */
	public void addWikiText(String symbol, String text, String meaning,
			String regex, int valueCount) {
		WikiTextManager.getContainer().add(
				this.new WikiText(symbol, text, meaning, regex, valueCount));
	}

	/**
	 * 添加Wiki体
	 * 
	 * @param symbol
	 *            符号
	 * @param meaning
	 *            含义
	 * 
	 * @param handler
	 *            自定义处理规则
	 * 
	 * @see #addWikiText(String, String, String, String, int)
	 */
	public void addWikiText(String symbol, String meaning,
			WikiTextHandler handler) {
		WikiTextManager.getContainer().add(
				this.new WikiText(symbol, meaning, handler));
	}

	/**
	 * 移除指定的Wiki体
	 * 
	 * @param symbol
	 *            符号
	 */
	public void removeWikiText(String symbol) {
		WikiTextManager.getContainer().remove(symbol);
	}

	/**
	 * 处理wiki体转义为HTML
	 * 
	 * @param target
	 *            需要处理的目标字符串
	 * @return 处理后的字符串
	 */
	public String process(String target) {
		if (target == null || "".equals(target))
			return "";
		String result = target;
		for (Iterator<WikiText> it = WikiTextManager.getContainer().iterator(); it
				.hasNext();) {
			result = replace(it.next(), result);
		}
		return result;
	}

	/**
	 * 匹配处理规则:如果存在对应的正则,则按照设定的正则进行特殊匹配 例如 [img[(\\w+)]] 可以匹配
	 * [img[xxx.jpg]];否则将默认按照首尾一致的原则进行匹配 例如 --(\\w+)-- 可以匹配
	 * --xxx--,但是所有组装出的正则中不应该在存在()
	 * 
	 * @param wt
	 * @param target
	 */
	private String replace(WikiText wt, String target) {
		if (wt.valueCount == -1) {
			if (wt.handler == null) // 如果没有对应的处理规则实现则不做处理
				return target;
			else
				return wt.handler.process(target);
		}

		String regex = currentRegex(wt);

		Pattern pattern = Pattern.compile(regex);
		for (Matcher matcher = pattern.matcher(target); matcher.find();) {
			// 获取当前完全匹配的组
			String orginalText = matcher.group();
			String newText = "";

			if (wt.valueCount == NONE_VALUE) {
				newText = wt.text;
			} else if (wt.valueCount == SINGLE_VALUE) {
				// 目标文本 如 [img[xxx.jpg]]通过这步后获取到xxx.jpg
				String targetText = matcher.group(1);

				// 拼接新的html的串 即 <img src="$1"> 还原为 <img src="xxx.jpg">
				newText = wt.text.replace("$1", targetText);
			} else {
				// 处理多值问题例如 <font color="$1" attr="$n">$2</font>
				for (int i = 1; i <= matcher.groupCount(); i++) {
					String targetText = matcher.group(i);
					String tmpReg = "{1}quot; + i;
					wt.text = newText = wt.text.replace(tmpReg, targetText);
				}
			}
			target = target.replace(orginalText, newText);
		}

		return target;
	}

	private String currentRegex(WikiText wt) {
		String regex = null;
		// 多值情况下需要自定义正则,并且要使用占位符
		if (wt.regex != null && !"".equals(wt.regex))
			regex = wt.regex;

		// 无值时正则本身就是符号
		else if (wt.valueCount == 0)
			regex = wt.symbol;

		// 默认当做单值,则正则为前后一致
		else
			regex = wt.symbol + "(.+?)" + wt.symbol;
		return regex;
	}

	// --------------------------------------------------------------

	/**
	 * Wiki体管理器
	 * 
	 * @author tangxiucai
	 * 
	 */
	private static class WikiTextManager {
		private static Set<WikiText> container = new HashSet<WikiText>();

		public static synchronized Set<WikiText> getContainer() {
			return container;
		}
	}

	/**
	 * Wiki特殊符号自定义解析接口
	 * 自定义解析规则需要注意参数为整个需要处理的字符串,有可能被应用了其他规则也可能没有,这取决于规则的应用顺序。 
	 * 通常自定义规则接口实现步骤:①进行匹配操作,只有在匹配成功的情况下对目标串进行处理否则返回原目标串,
	 * 而不能返回null或空串因为可能导致空指针异常; ②对匹配串进行迭代处理
	 * 实现示例:
	 * <code><pre>
	 * public String process(String target) {
			String regex = "--(.+?)--";
			if(Pattern.matches(regex, target)){
				Pattern pattern = Pattern.compile(regex);
				for(Matcher matcher = pattern.matcher(target); matcher.find();){
					String findStr = matcher.group();
					String includedStr = matcher.group(1);
					String newStr = "(已删除:" +includedStr+ ")";
					target = target.replaceAll(findStr, newStr);
				}
			}
			return target;
		}
	 *</pre></code>
	 * @author tangxiucai
	 * 
	 */
	private interface WikiTextHandler {
		/**
		 * 自定义处理过程,将目标字符串按照自己的解析规则转换成需要的字符串
		 * 
		 * @param target
		 *            需要处理的目标字符串
		 * @return 处理后的字符串
		 */
		String process(String target);
	}

	/**
	 * Wiki体
	 * 
	 * @author tangxiucai
	 * 
	 */
	private class WikiText {
		/**
		 * 符号 例如 --表示删除 ----表示横线
		 */
		public String symbol;

		/**
		 * 对应的html,用$1代表目标串的占位符
		 */
		public String text;

		/**
		 * 符号含义
		 */
		public String meaning;

		/**
		 * 符号匹配正则
		 */
		public String regex;

		/**
		 * 存储占位符个数 -1时说明存在自定义解析接口的实现
		 */
		public int valueCount;

		public WikiTextHandler handler = null;

		public WikiText(String symbol, String text, String meaning,
				String regex, int valueCount) {
			this.symbol = symbol;
			this.text = text;
			this.meaning = meaning;
			this.regex = regex;
			this.valueCount = valueCount;
		}

		public WikiText(String symbol, String meaning, WikiTextHandler handler) {
			this.symbol = symbol;
			this.meaning = meaning;
			this.handler = handler;
			this.valueCount = -1;
		}

		@Override
		public int hashCode() {
			return this.symbol.hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null || !(obj instanceof WikiText))
				return false;
			WikiText wt = (WikiText) obj;
			if (wt.symbol.equals(this.symbol))
				return true;
			return false;
		}
	}
}

分享到:
评论

相关推荐

    Wiki网站系统 jsp 源码

    Wiki系统通常支持特定的文本语法,如Markdown或WikiText,用于简化内容创作。源码中应包含解析这些语法并将其转换为HTML的逻辑。 9. **搜索功能** 为了方便用户查找信息,系统需要提供全文搜索功能。可能使用了如...

    dokuwiki安装包

    10. **搜索引擎友好**:DokuWiki的页面URL是搜索引擎友好的,这有助于提高页面的可发现性和SEO排名。 11. **用户管理**:DokuWiki支持多用户协作,并且有权限管理系统,可以设定不同用户的访问和编辑权限。你可以...

    dokuwiki2020-07-29Hogfather.zip

    在Hogfather版本中,DokuWiki还可能提升了性能和稳定性,例如通过优化数据库查询,提高页面加载速度,或者通过增强错误处理机制,降低系统崩溃的风险。这些改进使得DokuWiki在高并发环境下依然能保持流畅运行。 ...

    wiki.zh.bin

    《wiki.zh.bin》这个模型文件,正是包含了经过上述处理后的词向量,它可以被用于各种自然语言处理任务,如文本分类、情感分析、机器翻译等。使用时,开发者可以将这个bin模型加载到自己的项目中,通过查询词向量来...

    商业源码-编程源码-ScrewTurn Wiki 维基系统3.0源码.zip

    源码中会包含解析和渲染Markdown文本的算法,这对于学习文本处理和网页渲染技术非常有帮助。 5. **权限管理**:作为协作平台,ScrewTurn Wiki需要有强大的用户管理和权限控制系统。这部分源码将揭示如何实现角色、...

    NLP 搜索引擎

    百度作为中国领先的搜索引擎之一,一直致力于提升其NLP技术以更好地理解和处理中文语言。 - **目标宗旨**:“让百度更懂中文”,这是百度NLP团队的核心使命。 - **内部平台**:通过内部网站`http://nlp.baidu.com`...

    基于Wiki链接结构图聚类的领域词典构建方法

    自然语言处理技术在搜索引擎优化、智能客服系统、机器翻译、情感分析等多个领域都有着广泛的应用。 #### 领域词典的构建方法 领域词典是指针对特定领域所建立的专业词汇表或术语库,它对于提高自然语言处理任务的...

    AspWiKi v2.0 build 03.12-ASP源码.zip

    1. **页面创建与编辑**:用户可以创建新的Wiki页面,并对已有页面进行编辑,这通常涉及到服务器端的文本处理和存储。 2. **版本控制**:由于是Wiki系统,它应具备版本控制功能,允许用户查看和恢复之前的页面版本。 ...

    Wiki系统

    对于开发者来说,理解开源Wiki引擎的源代码可以帮助他们自定义功能、优化性能或开发新的Wiki应用。例如,MediaWiki(维基百科背后的技术)是用PHP编写的,它的源代码可以提供关于如何处理用户权限、页面存储、搜索和...

    Python-采用PythonFlaskRedisSQLite开发wiki系统

    由于Redis支持多种数据结构(如字符串、列表、集合、哈希表),因此它非常适合处理wiki系统的各种需求,如快速查找、存储用户会话信息等。 ### SQLite SQLite是一个嵌入式的关系型数据库,它不需要单独的服务器进程...

    fast-wiki-master.zip

    2. **源代码**:源代码是程序员用编程语言编写的原始文本,可以被编译器或解释器转化为机器可执行的代码。在 "fast-wiki-master" 中,源代码可能是用某种编程语言(如Python、JavaScript或Go)编写,用于实现wiki的...

    Wiki-mirror:Wiki的只读镜像

    这些框架可以处理HTTP请求,渲染静态HTML,并可能通过模板引擎(如Jinja2)将存储的数据转化为用户友好的格式。 此外,为了保持镜像的更新,可能需要定时运行数据抓取和更新的脚本,这可以借助Python的schedule库...

    Wiki-Search-engine:维基搜索引擎

    它可能是为了解决如何高效地在庞大的维基百科数据中查找相关信息的问题,可能涉及到搜索算法、文本处理以及信息检索技术。 **描述解析:** "CS218 倒排索引类,页面排名计算。 搜索引擎类" 这部分描述提到了两个...

    wiki:Nim中的wiki html生成器

    1. **解析器开发**:首先,我们需要创建一个解析器来理解Wiki文本的语法。这通常涉及到识别和处理诸如链接、标题、列表、内嵌代码块等元素。Nim的强大的字符串处理能力和正则表达式支持可以帮助我们快速构建这样的...

    wiki_content:存储库Wiki中使用的文件

    典型的Wiki系统包括MediaWiki(维基百科背后的技术)、Confluence(企业级知识管理工具)和DokuWiki(轻量级开源Wiki引擎)。它们提供了版本控制功能,确保了内容的准确性和历史记录。 **2. 存储库(Repository)**...

    smeagol:受Gollum启发的简单Wiki引擎

    **smeagol:受Gollum启发的简单Wiki引擎** `smeagol` 是一个基于Git的轻量级Wiki引擎,灵感来源于J.R.R. 托尔金的《魔戒》系列中的人物Gollum。Gollum在故事中与“魔戒”紧密相连,而`smeagol`则与版本控制系统Git...

    waliki:由Django和Git驱动的Wiki引擎

    **waliki:由Django和Git驱动的Wiki引擎** `waliki`是一个开源的、基于Web的Wiki系统,它的核心特点在于使用了流行的Web框架Django以及版本控制系统Git。这个强大的组合使得waliki具备了易用性、可扩展性和版本控制...

    Bergamot:基于Git的Wiki引擎

    佛手柑(Bergamot)是一个以Git为基础的Wiki引擎,它的设计目的是为了提供一个简单易用且版本控制的文档协作平台。Git作为一个分布式版本控制系统,被广泛应用于软件开发中,用来跟踪代码的修改历史。Bergamot将Git...

    Wikidoc - Wikibased Documentation-开源

    5. **librerias**:库文件夹包含各种必要的库和函数集,用于实现Wikidoc的各种功能,如文本解析、数据库操作、模板引擎等。这些库可能包含了第三方的开源组件,如PHP Markdown解析器,或者是为Wikidoc定制的专用工具...

Global site tag (gtag.js) - Google Analytics