Created
July 3, 2018 04:43
-
-
Save dailybird/2b4923643be85a836b29cbddbcce16c3 to your computer and use it in GitHub Desktop.
字符串匹配模式问题
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.logging.Logger; | |
import java.util.regex.Pattern; | |
public class PatternQuestion { | |
private static Logger logger = Logger.getLogger(PatternQuestion.class.toString()); | |
/** | |
* 请求参数: | |
* <p> | |
* 1. 匹配模式,如:aabb | |
* 2. 目标字符串:如:"北京 北京 杭州 杭州" | |
* <p> | |
* 测试用例: | |
* <p> | |
* 1. "abba" "北京 杭州 杭州 北京" => ture | |
* 2. "aabb" "北京 杭州 杭州 北京" => false | |
* 3. "abc" "北京 杭州 杭州 南京" => false | |
* 4. "acac" "北京 杭州 北京 广州" => false | |
* <p> | |
* 思路: | |
* <p> | |
* 利用正则中反向引用特性,实现此种需求的匹配,如: | |
* | |
* @param args | |
*/ | |
public static void main(String[] args) { | |
if (args.length < 2) { | |
logger.info("@@@@ 用法:<model> <target>"); | |
System.exit(1); | |
} | |
// 用 model 表示用户指定的「模式」 | |
// 用 pattern 表示正则 | |
String modelStr = args[0]; | |
String target = args[1]; | |
logger.info("@@@@ 匹配模式为:" + modelStr + ",测试内容为:" + target); | |
final String regexAnyWithoutSpace = "([^\\s]+)"; | |
final String regexSpace = "\\s"; | |
// key 为字符,value 为反向引用序号,用于构造正则表达式 | |
Map<String, Integer> regexPlaceholderIndexMap = new HashMap<>(); | |
// 正则中,反向引用序号从 1 开始 | |
Integer regexPlaceholderIndex = 1; | |
// 生成正则表达式 | |
List<String> regexPatternArray = new ArrayList<>(); | |
Integer patternLength = modelStr.length(); | |
for (Integer index = 0; index < patternLength; index++) { | |
String needle = new String(new char[]{modelStr.charAt(index)}); | |
Integer currentPlaceHolderIndex = regexPlaceholderIndexMap.get(needle); | |
if (currentPlaceHolderIndex == null) { | |
// 如果为空,证明这一字符刚刚出现 | |
regexPatternArray.add(regexAnyWithoutSpace); | |
regexPlaceholderIndexMap.put(needle, regexPlaceholderIndex); | |
regexPlaceholderIndex++; | |
} else { | |
// 如果不为空,则证明为先前的某一字符,需用反向引用方式指代 | |
regexPatternArray.add(String.format("\\%d", currentPlaceHolderIndex)); | |
} | |
} | |
// 将正则各个部分用空格串起来,与需求匹配 | |
// 并为其增加头尾限制 | |
String patternStr = String.format("^%s$", String.join(regexSpace, regexPatternArray)); | |
logger.info("@@@@ 组装的正则表达式为:" + patternStr); | |
Pattern pattern = Pattern.compile(patternStr); | |
Boolean isMatch = pattern.matcher(target).find(); | |
logger.info("@@@@ 字符串匹配结果为:" + isMatch); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment