RegexpKeyedMap

http://wiki.apache.org/jakarta/RegexpKeyedMap

RegexHashMap

https://heideltime.googlecode.com/hg-history/a354341d349e75262884706b830f237fd9eeb269/src/de/unihd/dbs/uima/annotator/heideltime/resources/RegexHashMap.java

原理基本都是get的时候去遍历key值,逐个正则匹配,效率不高。

nginx有支持通配符的实现,有时间可以了解下实现。

RegexHashMap

package de.unihd.dbs.uima.annotator.heideltime.resources;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern; /**
* Implements a HashMap extended with regular expression keys and caching functionality.
*
* @author Julian Zell
*
*/
public class RegexHashMap<T> implements Map<String, T> { private HashMap<String, T> container = new HashMap<String, T>();
private HashMap<String, T> cache = new HashMap<String, T>(); /**
* clears both the container and the cache hashmaps
*/
public void clear() {
container.clear();
cache.clear();
} /**
* checks whether the cache or container contain a specific key, then evaluates the
* container's keys as regexes and checks whether they match the specific key.
*/
public boolean containsKey(Object key) {
// the key is a direct hit from our cache
if(cache.containsKey(key))
return true;
// the key is a direct hit from our hashmap
if(container.containsKey(key))
return true; // check if the requested key is a matching string of a regex key from our container
Iterator<String> regexKeys = container.keySet().iterator();
while(regexKeys.hasNext()) {
if(Pattern.matches(regexKeys.next(), (String) key))
return true;
} // if the three previous tests yield no result, the key does not exist
return false;
} /**
* checks whether a specific value is container within either container or cache
*/
public boolean containsValue(Object value) {
// the value is a direct hit from our cache
if(cache.containsValue(value))
return true;
// the value is a direct hit from our hashmap
if(container.containsValue(value))
return true; // otherwise, the value isn't within this object
return false;
} /**
* returns a merged entryset containing within both the container and cache entrysets
*/
public Set<Entry<String, T>> entrySet() {
// prepare the container
HashSet<Entry<String, T>> set = new HashSet<Entry<String, T>>();
// add the set from our container
set.addAll(container.entrySet());
// add the set from our cache
set.addAll(cache.entrySet()); return set;
} /**
* checks whether the requested key has a direct match in either cache or container, and if it
* doesn't, also evaluates the container's keyset as regexes to match against the input key and
* if any of those methods yield a value, returns that value
* if a value is found doing regex evaluation, use that regex-key's match as a non-regex
* key with the regex's value to form a new entry in the cache.
*/
public T get(Object key) {
// output for requested key null is the value null; normal Map behavior
if(key == null) return null; T result = null;
if((result = cache.get(key)) != null) {
// if the requested key maps to a value in the cache
return result;
} else if((result = container.get(key)) != null) {
// if the requested key maps to a value in the container
return result;
} else {
// check if the requested key is a matching string of a regex key from our container
Iterator<Entry<String, T>> regexKeys = container.entrySet().iterator();
while(regexKeys.hasNext()) {
// prepare current entry
Entry<String, T> entry = regexKeys.next();
// check if the key is a regex matching the input key
if(Pattern.matches(entry.getKey(), (String) key)) {
putCache((String) key, entry.getValue());
return entry.getValue();
}
}
} // no value for the given key was found in any of container/cache/regexkey-container
return null;
} /**
* checks whether both container and cache are empty
*/
public boolean isEmpty() {
return container.isEmpty() && cache.isEmpty();
} /**
* returns the keysets of both the container and cache hashmaps
*/
public Set<String> keySet() {
// prepare container
HashSet<String> set = new HashSet<String>();
// add container keys
set.addAll(container.keySet());
// add cache keys
set.addAll(cache.keySet()); return set;
} /**
* associates a key with a value in the container hashmap
*/
public T put(String key, T value) {
return container.put(key, value);
} /**
* associates a key with a value in the cache hashmap.
* @param key Key to map from
* @param value Value to map to
* @return previous value associated with the key, or null if unassociated before
*/
public T putCache(String key, T value) {
return cache.put(key, value);
} /**
* adds a map to the container
*/
public void putAll(Map<? extends String, ? extends T> m) {
container.putAll(m);
} /**
* removes a specific key's association from the container
*/
public T remove(Object key) {
return container.remove(key);
} /**
* returns the combined size of container and cache
*/
public int size() {
return container.size() + cache.size();
} /**
* returns the combined collection of both the values of the container as well as
* the cache.
*/
public Collection<T> values() {
// prepare set
HashSet<T> set = new HashSet<T>();
// add all container values
set.addAll(container.values());
// add all cache values
set.addAll(cache.values()); return set;
}
}

RegexpKeyedMap

package org.apache.regexp.collections;

import java.util.HashMap;
import java.util.Iterator; import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException; /**
* This map implementation uses a hashmap as the underlying storage.
* Note that the keySet() method will return a set of regular expressions rather than actual keys.
* The put() method uses a regexp as a key.
* The get() method gets any value that matches one of the regexps. If there is more than one matching regexp, the first one
* encountered is returned - and hence could be indeterminate!
*
* @author Manik Surtani
*
*/
public class RegexpKeyedMap extends HashMap
{
public Object put(Object key, Object value)
{
if (key instanceof String)
return super.put(key, value);
else
throw new RuntimeException("RegexpKeyedMap - only accepts Strings as keys.");
} /**
* The key passed in should always be a String. The map will return the first element whose key, treated as a regular expression, matches the key passed in
* NOTE: It is possible for this map to have more than one return value, for example, if a key is passed into get() which matches more than one regexp.
*
* E.g., consider the following keys in the map - '[A-Za-z]*' and 'Hello'. Passing in 'Hello' as a key to the get() method would match either of the regexps,
* and whichever apears first in the map (which is indeterminate) will be returned.
*
*/
public Object get(Object key)
{
Iterator regexps = keySet().iterator();
String keyString;
Object result = null; String stringToMatch = cleanKey( key ); while (regexps.hasNext())
{
keyString = regexps.next().toString();
try
{
RE regexp = new RE(keyString);
if (regexp.match(stringToMatch))
{
result = super.get(keyString);
break;
}
}
catch (RESyntaxException e)
{
// invalid regexp. ignore?
}
}
return result;
} /**
* Strip any 'dirty' chars from the key we are searching for,
* otherwise we end up with funny results from the RE
*
* @param obj
* @return
*/
private String cleanKey( Object obj )
{
String retVal = obj.toString(); // remove any '^' from start of key - prevents the RE from matching !?!?
return ( retVal.charAt(0) == '^' ) ? retVal.substring(1) : retVal;
} }

支持正则或通配符的hashmap的更多相关文章

  1. js进阶js中支持正则的四个常用字符串函数(search march replace split)

    js进阶js中支持正则的四个常用字符串函数(search march replace split) 一.总结 代码中详细四个函数的用法 search march replace split 二.js进 ...

  2. flask框架(六): 实现支持正则的路由

    一:默认路由 @app.route('/user/<username>') @app.route('/post/<int:post_id>') @app.route('/pos ...

  3. JS不支持正则中的负向零宽断言

    今天在项目中用到了正则表达式,并且需要用负向零宽断言 (?<=exp) 进行筛选,结果运行时报 Invalid group 错,一开始以为是自己很久没用表达式写错了,查阅了一下正则语法后发现并没 ...

  4. flask框架(五)——支持正则写法、模板用法、请求响应、session

    如果用正则的话,我们要用自定义的路由. 1导入from werkzeug.routing import BaseConverter 2我先要写一个类,然后继承BaseConverter,然后实现__i ...

  5. http服务详解(2)——httpd2.2的配置文件常见设置

    摘要:一个服务的配置文件非常重要,弄懂配置文件是熟练掌握服务的必要前提. 一.httpd-2.2常见文件介绍 (1)配置文件: 主配置文件尽量别改,改自己的子配置文件 /etc/httpd/conf/ ...

  6. Windows 上面优秀的工具软件推荐

    Windows 上面优秀的工具软件推荐 一.下载软件 1.速盘 - 度盘神器 简介: 使百度网盘保持全速下载免受限速困扰! 下载: speedpan 2.http下载工具 百度网盘破解下载器:prox ...

  7. http服务详解(2)——httpd的配置文件常见设置

    HTTP服务器应用 http服务器程序 httpd apache nginx lighttpd 应用程序服务器 IIS .asp tomcat .jsp jetty 开源的servlet容器,基于Ja ...

  8. 交互输入与for语句

    交互输入与for语句 1.   交互输入 read命令可以同时定义多个变量值:输入的内容默认以空格为分隔符,将值输入到对应的变量中:read尽量避免交互 如果默认值过多,最后所有的值会被赋予给最有一个 ...

  9. Shell:Day05.笔记

    交互输入与for语句 1.交互输入 read  Python中用input()函数,进行输入:  read命令同时可以定义多个变量值:而输入的内容默认以空格为分隔符,将值输入到对应的变量中: 如果默认 ...

随机推荐

  1. MySQL 性能优化的最佳20多条经验分享[转]

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.     当我们去设计数据库表结构, ...

  2. SVN使用安装

    SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...

  3. General protection fault Exceptions in Linux/IA32 Systems

    Computer Systems A Programmer's Perspective Second Edition Exception number Description Exception cl ...

  4. 抓包工具Charles 【转】

      今天就来看一下Mac上如何进行抓包,之前有一篇文章介绍了使用Fidder进行抓包 http://blog.csdn.net/jiangwei0910410003/article/details/1 ...

  5. 一段检测IP设备是否在线的代码

    原理是通过发送ARP包来检测 uses WinSock function SendARP(const DestIP, SrcIP: Cardinal; pMacAddr: PULONG; var Ph ...

  6. NRF51822之app_button使用

    我们现在开始使用app_button,为什么要使用这个来替代直接使用GPIOTE呢? 因为我们在手册中可以看到如果一直开启GPIOTE in模式的需要需要很大电流.所以我们需要使用RTC来“周期”的查 ...

  7. 管子&小白

    管夷吾已入朝,稽首谢罪,桓公亲手扶起,赐之以坐.夷吾曰:“臣乃俘戮之余,得蒙宥死,实为万幸,敢辱过礼!”桓公曰:“寡人有问于子,子必坐,然后敢请."夷吾再拜就坐. 桓公曰:“齐,千乘之国,先 ...

  8. 最大子序列和 o(n)

    问题: 给定一整数序列A1, A2,... An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大 例如:整数序列-2, 11, -4, 13, -5, 2, -5, -3, ...

  9. frameset、frame、noframes和iframe的区别

    原网站地址:http://nmyun.blog.51cto.com/448726/155268 ■ 框架概念 :所谓框架便是网页画面分成几个框窗,同时取得多个 URL.只需要 <frameset ...

  10. 正则表达式lastIndex属性浅析

    有这样一段代码: var newDateStr = " 11 13:48:18"; var reg = new RegExp("[0-9]+","g& ...