Javascript正则表达难倒

时间:2017-01-24 21:54:53

标签: javascript regex

您好我正在使用javascript应用程序并需要帮助搞清楚这个正则表达式

我有一系列字符串。它们是动态的,但确实有一套固定的模式。

name eq 'abc'
id in 'def'
key | operator | value

然后我有一个修饰符'has'

has name eq 'abc'
!has id
has address eq '123 sesame street'
|modifier | key | operator | value

我能够使用此正则表达式提取修饰符和键没有问题

new RegExp(/(^(\s*!?has\s+)?([^\s]+)|(^\s*[^\s]+))/i)

但是当我有一个与修饰符

相同的键时会出现问题
has eq '123'

上面的正则表达式返回'has eq',其中我只需要'has'

has has eq '123'

以上返回正确'已经'

需要处理大量的运算符,但它们是设定值

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:4)

您需要具体完整地指定所有有效语法:

var keyval = ''

keyval += "^\s*(\w+)\s+eq\s+'(.*)'$";      // for key eq 'val'
keyval += "|^\s*has\s(\w+)\s+eq\s+'(.*)'$"; // for has key eq 'val'

new RegExp(keyval, 'i');

我不确定您是否需要has var!has var行没有值,如果您可以添加:

keyval += "|^\s*!?has\s+(\w+)$";  // for has key and !has key

请注意,正则表达式的主要问题是无法识别eq是一个重要的关键字。

附加说明:

就我个人而言,我不会使用一个正则表达式。这样做会使正则表达式变得冗长而复杂,并且还会使提取匹配变得困难。你可以使用上面的技巧打破长期的正则表达式,但在我看来,最好使用许多较小的正则表达式。我写的内容如下:

var key_equal_pattern     = /^\s*(\w+)\s+eq\s+'(.*)'$/i;
var has_key_equal_pattern = /^\s*has\s(\w+)\s+eq\s+'(.*)'$/i;
var has_patten            = /^\s*!?has\s+(\w+)$/i;

if ((m = input.match(key_equal_pattern)) !== null) {
    // handle match
}
else if  ((m = input.match(has_key_equal_pattern)) !== null) {
    // handle match
}
else if  ((m = input.match(has_patten)) !== null) {
    // handle match
}

与巨型正则表达式相比,这更易于维护。请注意,虽然常见的说法是你不能用正则表达式解析像html这样的东西,人们真正想说的是你不能在一个正则表达式中做到这一点。几乎所有的html解析器都在标记化过程中使用regexp,然后使用iffor循环来处理数据结构。

答案 1 :(得分:1)

您的输入数据似乎只遵循几种可能的模式:

mod key
    key op val
mod key op val

如果这代表了您的所有数据,并且您确信您的输入数据格式正确,则一个简单的快捷方式是提取所有令牌,并将key op val模式与其他模式区分开来。提取的令牌。

以下演示说明了正确识别问题测试用例的方法:

function extract(str){
  var result = str.match(/'[^']*'|\S+/g);
  if(result.length == 3){// key op val
    return {
      key: result[0],
      op:  result[1],
      val: result[2]
    }
  } else {// mod key OR mod key op val
    return {
      mod: result[0],
      key: result[1],
      op:  result[2],
      val: result[3]
    }
  }
}

console.log(extract("!has id"));
console.log(extract("has eq '123'"));
console.log(extract("has has eq '123'"));