001package gu.sql2java; 002 003import com.google.common.base.Function; 004 005/** 006 * 字符串模糊匹配类型 007 * @author guyadong 008 * 009 */ 010public enum StringMatchType implements Function<String, String>{ 011 /** 012 * 精确匹配, 013 * 比较字符串是否与pattern完全相等 014 */ 015 EXACTLY_MATCH, 016 /** 017 * 字符串比较匹配, 018 * 比较字符串是否以pattern起始,如 'hello' 匹配 'hello,world' 019 */ 020 CMP_LEFT_MATCH, 021 /** 022 * 字符串比较匹配, 023 * 比较字符串是否以pattern结尾,如 'world' 匹配 'hello,world' 024 */ 025 CMP_RIGHT_MATCH, 026 /** 027 * 字符串比较匹配, 028 * 比较字符串是否包含pattern,如 'wo' 匹配 'hello,world' 029 */ 030 CMP_MATCH, 031 /** 032 * 支持通配符的字符串比较匹配 033 * pattern中允许包含通配符('*','?'),'*'匹配任意0或多个字符,'?'匹配任意单个字符 034 * 比较字符串是否包含pattern,如 '1*2房' 匹配 '1032房间',匹配'10楼/32房间','1?2'匹配'1楼2单元','1?2房'不匹配'1032房间' 035 */ 036 WILDCARD_MATCH, 037 /** 038 * 数字模糊匹配 039 * pattern必须全部为数字, 040 * 比较字符串中所有数字组成的字符串是否包含pattern数字序列,如'102'匹配'102-2房间','122'匹配'/1楼/2单元/2房间' 041 */ 042 DIGIT_FUZZY_MATCH, 043 /** 044 * 左侧数字模糊匹配 045 * pattern必须全部为数字, 046 * 比较字符串中所有数字组成的字符串是否以pattern数字序列起始,如'102'匹配'10幛/22房间',但不匹配'/1楼/102房间' 047 */ 048 DIGIT_FUZZY_LEFT_MATCH, 049 /** 050 * 右侧数字模糊匹配 051 * pattern必须全部为数字, 052 * 比较字符串中所有数字组成的字符串是否以pattern数字序列结尾,如'102'匹配'/1楼/102房间',但不匹配'102-2房间' 053 */ 054 DIGIT_FUZZY_RIGHT_MATCH, 055 /** 056 * 带分隔符'/'的数字模糊匹配 057 * pattern必须为数字及分隔符'/','-','.',分隔符会被替换为'/', 058 * 比较字符串中所有数字组成的字符串是否包含pattern数字序列,如'1-102'匹配'1楼/102房间',不匹配'1楼/1102房间' 059 */ 060 DIGIT_SEP_FUZZY_MATCH, 061 /** 062 * 带分隔符'/'的左侧数字模糊匹配 063 * pattern必须为数字及分隔符'/','-','.',分隔符会被替换为'/', 064 * 比较字符串中所有数字组成的字符串是否以pattern数字起始,如'1-102'匹配'1楼/102-2房间',不匹配'1幢/1单元/102房间' 065 */ 066 DIGIT_SEP_FUZZY_LEFT_MATCH, 067 /** 068 * 带分隔符'/'的右侧数字模糊匹配 069 * pattern必须为数字及分隔符'/','-','.',分隔符会被替换为'/', 070 * 比较字符串中所有数字组成的字符串是否以pattern数字结尾,如'1/102'匹配'1楼/1单元/102房间',不匹配'1幢/102-2房间' 071 */ 072 DIGIT_SEP_FUZZY_RIGHT_MATCH, 073 /** 074 * 正则表达式匹配 075 * pattern为正则表达式,表达式,如果pattern不以'^'或'|$'结尾,会自动加上'^.*'开头和'.*$'结尾 076 * 比较字符串是否有满足pattern的正则匹配,如'1\d+'匹配'/1楼/102房间' 077 */ 078 REGEX_MATCH, 079 /** 080 * 全字模糊匹配 081 * pattern为要匹配的字符串序列 082 * 比较字符串是否混入pattern字符序列,如'12房'匹配'/1楼/102房间','王鹏'匹配'王小鹏','王鹏程','周王鹏','王鹏' 083 */ 084 FUZZY_MATCH; 085 086 @Override 087 public String apply(String input) { 088 switch (this) { 089 case WILDCARD_MATCH: 090 return "^.*" + input.replace("*", ".*").replace("?", ".") + ".*$"; 091 case FUZZY_MATCH: 092 return "^.*" + input.replaceAll(".", "$0.*"); 093 case DIGIT_FUZZY_MATCH: 094 return "^.*" + input.replaceAll(".", "$0[^\\\\d]*") + ".*$"; 095 case DIGIT_FUZZY_LEFT_MATCH: 096 return "^[^\\d]*" + input.replaceAll(".", "$0[^\\\\d]*") + ".*$"; 097 case DIGIT_FUZZY_RIGHT_MATCH: 098 return "^.*" + input.replaceAll(".", "[^\\\\d]*$0") + "[^\\d]*$"; 099 case DIGIT_SEP_FUZZY_MATCH: 100 // '.' '-' 为分隔符替换为 '/' 101 return "^.*" + input.replaceAll("[\\\\.\\\\-]+", "/").replaceAll(".", "$0[^\\\\d]*") + ".*$"; 102 case DIGIT_SEP_FUZZY_LEFT_MATCH: 103 // '.' '-' 为分隔符替换为 '/' 104 return "^[^\\d]*" + input.replaceAll("[\\\\.\\\\-]+", "/").replaceAll(".", "$0[^\\\\d]*") + ".*$"; 105 case DIGIT_SEP_FUZZY_RIGHT_MATCH: 106 // '.' '-' 为分隔符替换为 '/' 107 return "^.*" + input.replaceAll("[\\\\.\\\\-]+", "/").replaceAll(".", "[^\\\\d]*$0") + "[^\\d]*$"; 108 case REGEX_MATCH: 109 if(!input.startsWith("^")){ 110 input = "^.*" + input; 111 } 112 if(!input.endsWith("^")){ 113 input = input + ".*$"; 114 } 115 return input; 116 case CMP_LEFT_MATCH: 117 case CMP_RIGHT_MATCH: 118 case CMP_MATCH: 119 case EXACTLY_MATCH: 120 default: 121 return input; 122 } 123 } 124 public IStringMatchFilter createMatchFilter(){ 125 switch (this) { 126 case CMP_LEFT_MATCH: 127 case CMP_RIGHT_MATCH: 128 case CMP_MATCH: 129 case EXACTLY_MATCH: 130 return new BaseFuzzyMatchFilter.DefaultStringMatcher(this); 131 default: 132 return new BaseFuzzyMatchFilter.RegexFilter().setPatternFormater(this); 133 } 134 } 135}