有没有办法指定一个与其他任何一个都不匹配的正则表达式?

时间:2016-09-14 04:47:11

标签: java regex

让我说我有这样的事情:

    pattern = new Pattern[6];
    pattern[0] = Pattern.compile("^\\s*(NAME\\:\\s*)\\s(\\w+)");
    pattern[1] = Pattern.compile("^\\s*(AGE\\:\\s*)\\s(\\d+)");
    pattern[2] = Pattern.compile("^\\s*(ADDRESS\\:\\s)(\\w+)");
    pattern[3] = Pattern.compile("^\\s*(BIRTHDAY\\:\\s)(\\d+)\\:(\\d+)\\:(\\d+)");        
    pattern[4] = Pattern.compile("(?=\\s*\\*)(^\\**)");
    pattern[5] = Pattern.compile("\\S+|[^\\s*.+\\s*]");

模式4的要点是捕获后跟*的注释,模式5是捕获其他模式不能的其他所有内容。然后Matcher dp检查模式是否是LookAhead预期返回true或false的模式。

    public boolean lookAhead () {
        while ((line = buff.readLine()) != null) {
                 Pattern different = Pattern.compile("^[^(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)]");                
                 Matcher comment = pattern[4].matcher(line);
                 Matcher diff = different.matcher(line);
                 Matcher name = pattern[0].matcher(line);
                 if (comment.find() || different.find() /*|| name.find()*/)               
                     continue;
                    Matcher dp = pattern[0].matcher(line);
                    dpla = dp.find();
                    break;
                 }
        }
        return dpla;
     }

评论被忽略,所有随机错误如:“feifiejfie”也是如此。但是,如果文本类似于“NAME 7987997 GSGSGE 456”,则应将其视为错误,但事实并非如此。如果取消注释name.find,它将始终有效,但它永远不会返回false。

2 个答案:

答案 0 :(得分:2)

让我们简单地采取一些不同的方法。我认为,实质上,你有一些输入字符串;然后你有一个可能包含你感兴趣的匹配器的不同正则表的列表。你在代码中做了很多匹配,最后只返回一个布尔值;这似乎没用;所以我打算让你知道如何以不同的方式做事。

 class RegexListMatcher {
   private final Map<String, Pattern> patternsById;
   private final String inputToMatchOn;

   private final String matchingId;
   private final String matchResult;

   RegexListMatcher(Map<String, Pattern> patternsById, inputToMatchOn) {
     this.patterns... = patterns
     this.input... = input

     matchingId = findMatchingId();
     if (matchingId == null) {
        matchResult = null;
     } else {
        matchResult = getMatchResult();
     }
   }

   private final String findMatchingId() {
     for (Entry<String, Pattern> entry : patternsById) {
       if entry.value matches the given input return entry.key

     otherwise return null
   }

   private final String getMatchResult() {
     Pattern pattern = patternsById.get(matchingId);
     return the value matched within input 
   }

   public boolean hasMatch() { return matchingID != null; }
   public String getMatchId() ...
   public String getMatchResult() ...

用作:

 private final static Map<String, Pattern> RULES = new HashMap<>();
 RULES.put("NAME", Pattern.compile("^\\s*(NAME\\:\\s*)\\s(\\w+)"));
 ...

 RegexListMatcher listMatcher = new RegexListMatcher(RULES, someInputString);
 if (listMatcher.hasMatch()) { 
   one of the rules matched
 } else {
   no match at all
 }

我实施的关键点:你有一个潜在模式列表;如果其中一个匹配,您肯定对输入中匹配的值感兴趣。并且惊喜:如果没有一个模式匹配,那么你也知道。因为RegexListMatcher可以告诉你。

当然,代码多于你的代码;但是例如:根本没有任何对某个数组索引的硬编码访问。显然,上面是部分伪代码,但我想它应该足以让你开始。

答案 1 :(得分:2)

我今天能够解决问题!对不起,如果我没有很好地解释我的问题,因为我必须编写更简单的正则表达式以试图解释这个问题,也许我错过了一些重要的观点来得到一个好的答案。与我的相比,这是一段非常简化的代码。主要的问题是,虽然评论和所有不是模式(模式&#39;错误&#39;否定一切以其他模式开始)将被检测到并且将继续While循环,如果模式从NAME:或AGE:等开始,这意味着它与“错误”不同。模式,所以它不会继续循环,但是这不应该发生,因为它只应该在检测到有效模式时停止循环。所以我做的是这个:

Pattern legit = Pattern.compile("^[(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)");
Matcher leg = legit.matcher(line);

此模式的要点是确定注释和错误失败时可能的情况。如果他们这样做,他们需要检查有效的是否失败:

(leg.find() && (!name.find() && !age.find() && !addr.find() && !bd.find())))

您可以通过参数中的int选择要查找的模式,它将更改此项:

Matcher input = pattern[a].matcher(line);
                 if (!input.find() ...)

所以所有组合都是这样的:

public boolean lookAhead (int a) {
        Pattern error = Pattern.compile("^[^(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)]");
        Pattern legit = Pattern.compile("^[(\\s*NAME.*)(\\s*AGE.*)(\\s*ADDRESS.*)(\\s*BIRTHDAY.*)");
        while ((line = buff.readLine()) != null) {                                
                 Matcher comment = pattern[4].matcher(line);
                 Matcher err = error.matcher(line);
                 Matcher leg = legit.matcher(line);
                 Matcher name = pattern[0].matcher(line);
                 Matcher age = pattern[1].matcher(line);
                 Matcher addr = pattern[2].matcher(line);
                 Matcher bd = pattern[3].matcher(line);
                 Matcher input = pattern[a].matcher(line);
                 if (!input.find() && (comment.find() || err.find() || (leg.find() && (!name.find() && !age.find() && !addr.find() && !bd.find())))               
                     continue;
                    Matcher dp = pattern[a].matcher(line);
                    dpla = dp.find();
                    break;
                 }
        }
        return dpla;
     }

完全符合我的要求:D