您好我正在使用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'
以上返回正确'已经'
需要处理大量的运算符,但它们是设定值
任何帮助将不胜感激
答案 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,然后使用if
和for
循环来处理数据结构。
答案 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'"));