Phasmida Java字符串处理工具

Phasmida

1.什么是phasmida?

phasmida 是一个字符串的处理工具,旨在通过一段简单的链式表达式描述并匹配出字符串中某些存在的特征,作为程序员的你应该能想到另外一个的东西,正则表达式。工作中有项目需要大量针对字符串做match,识别其中的特征,因为正则表达式读写都比较费劲,很多东西又需要自定义,于是最终就有了phasmida。但是Phasmida并不是为了完全替代正则,提供一种新的实现方式,使得可以更加灵活地处理该字符串特征问题。

phasmida的一些设计:

链式表达式

读写都很容易,对初学者友好

自定义规则片段,提高灵活性

phasmida [fæz'maɪdə] 是一个生物学上的名词,译为竹节虫目,项目也取其本意,表达式一节节链式组成,像一个竹节虫。


竹节虫(来源见水印)

项目源码地址:https://github.com/fengcone/phasmida

2.使用phasmida

添加依赖:

<dependency>
      <groupId>com.github.fengcone</groupId>
      <artifactId>phasmida</artifactId>
      <version>1.1</version>
</dependency>

第一个phasmida:识别某几个字符串

    RegistryUtil.registerStandardFragments();\\注册标准片段库
    PhasmidaFactory factory = new PhasmidaFactory(); \\phasmida工厂类
    Phasmida phasmida = factory.getPhasmida("with(Hello).with( world, phasmida)");\\通过 表达式获取Phasmida对象
    PhasmidaContext context = new PhasmidaContext("Hello world");\\定义上下文对象
    boolean process = phasmida.process(context);\\调用处理方法,返回是否能被匹配上,匹配的其他信息会在Context对象中

最终Context对象:
PhasmidaContext [string=Hello phasmida, endIndex=14, startIndex=5, indexPairs=[IndexPair [startIndex=0, endIndex=5, fragmentsIndex=0], IndexPair [startIndex=5, endIndex=14, fragmentsIndex=1]]]

3.Phasmida的核心设计

phasmida表达式

  with(北京).without(路,街,银行)

所有的Phasmida表达式由两个部分组成,signWord 以及括号中的参数,如上表达式中with以及without为signword,而括号中的“北京”,“路”,“银行”等 为参数

Fragment接口

public interface Fragment {

    /**
     * @param context 处理的上下文
     * @return 是否成功被处理
     */
    boolean process(PhasmidaContext context);

    /**
     * 回调方法,执行完成下一个Fragment后需要返回判断的方法 典型fragment为without,withAnything
     *
     * @param context 处理的上下文
     * @return 处理成功与否
     */
    boolean processAfterNext(PhasmidaContext context);

    /**
     * 获得表达式中的关键词语
     *
     * @param phasmida       该Fragment所属的Phasmida
     * @param words          关键词语
     * @param fragmentsIndex 这个Fragment在表达式中为位置索引
     * @param signWord       注册时所用的关键词
     */
    void init(Phasmida phasmida, String[] words, int fragmentsIndex, String signWord);

}

fragment之间方法调用顺序

方法调用顺序

init方法是在初始化时,解析参数后传入

注册中心

com.fengcone.phasmida.registry.PhasmidaRegistry

\\通过向注册中心注册,注册,第一个参数是signWord,第二个参数是具体实现,注意,实现类必须实现Fragment接口
PhasmidaRegistry.register(new String[]{"with"}, WithFragment.class);

互斥关系注册

某一些Fragment,彼此之间不能组成有效的Phasmida表达式,如“without(非).withAnything(5) ”等,可以通过注册互斥关系来避免,通过调用以下方法实现
com.fengcone.phasmida.registry.MutexRelationRegistry

\\这个方法是一个变长参数,可接受多个Fragment对象,代表这样组合的Fragment为互斥关系
MutexRelationRegistry.addMutexRelation(WithoutFragment.class, WithAnythingFragment.class);

PhasmidaContext 上下文

该对象为处理过程的中间对象,fragment的process方法以及processAfterNext,以及Phasmida对象都是在处理过程总 都是通过该上下文传递数据,感知环境

    \\需要被处理的字符串
    String string;

    \\最后一个成功的Fragment的结束游标
    int endIndex;

    \\最后一个成功的Fragment的开始游标
    int startIndex;

    \\所有成功的Fragment中匹配成功的开始与结束游标
    List<IndexPair> indexPairs;

    \\通过设置或获取该值,感知环境中是否应该使用头部方法
    boolean nextNeedBeHead;

    \\最终整个Phasmida的处理结果
    boolean result;

PhasmidaFactory 工厂类

该类通过接受一个字符串表达式实例化一个Phasmida对象,典型用法如下:

Phasmida phasmida =  new PhasmidaFactory().getPhasmida("with(Hello).with( world, phasmida)");

4.标准Fragment库介绍

withFragment

表达式:with(王).with(建国,建军)
以上表示匹配:“王建国” 、“王建军” 两个字符串,参数中匹配的是或者的关系,且必须匹配上一个

withoutFragment

表达式:without(黑).with(龙泉镇)
以上匹配 :“龙泉镇” 字符串,且不能为“黑龙泉镇”

表达式:with(龙泉).without(乡)
以上匹配 :“龙泉” 字符串,但不能为“龙泉乡”

withAnythingFragment

表达式:withAnything(5).with(北京)
以上匹配的是带有“北京“的字符串,并且”北京“前面的字符串不能超过5个

表达式:with(北京).withAnything(5).with(朝阳)

以上匹配的是带有”北京“和”朝阳“的字符串,并且 ”北京“与”朝阳“ 之间的其他字符串不超过5个

withNumRangeFragment

表达式:withNumRange(100,200)

以上匹配的是 字符串的的数字,并且这个数字在100到200之间,

withCharRangeFragment

表达式:withCharRange(0-9,A-Z,a-z,-,_,2+)

该表达式中除了最后一个参数,其他均代表范围,如果最终程序会解析以”-“ 分割的范围,如正则表达式中 0-9A-Z 等,这个最终代表的是在unicode中这些Char的数字范围,会将待匹配字符串中单个字符进行范围比较,如果不以”-“分割,那么代表能够对单char进行匹配如上表达式中的 ”-,_,“ 部分。

该表达式最后一个 参数形式为"2+","2","2-" 表示为参数中的范围最终能匹配的个数,分别表示,至少匹配两次,只能匹配两次,至多匹配两次。

另外该表达式支持unicode
如:withCharRange(\u0031-\u0033,2) 表达式等同于 withCharRange(1-3,2)

headFragment & tailFragment

表达式:head().with(开心,悲伤).tail()
这两个表达式没有参数,必须与其他的Fragment搭配使用,代表掐头去尾,与正则中 ^ 和$ 功能一致

标准库还在持续完善中....

5.典型应用

识别邮箱:

withCharRange(0-9,A-Z,a-z,-,_,1+).with(@).withCharRange(0-9,A-Z,a-z,-,_,1+).with(.).withCharRange(0-9,A-Z,a-z,-,_,1+)

识别电话号码:

with(1).with(3,9,7,5,4).withCharRange(0-9,9)

识别门牌号:

withNumRange(0,1000).with(房,室,单元,-,号楼,栋,号院,房间,门,座,层).withNumRange(0,1000)

6.贡献代码

如果您能向该项目贡献代码,维护者将不胜感激。当您发现问题或者想要贡献代码,可以生成一个 issue 或一个pull request.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容