正则表达式字符串捕获JavaScript

时间:2013-05-03 12:42:43

标签: javascript jquery regex

我是javascript中的regex新手。我有一个类似下面的字符串:

  

这里的东西(这里的其他东西(这里有些东西)和其他东西其他东西)asdf( asdfas)这里的东西某事(这里的其他内容其他别的东西)“

从上面的字符串中,我试图根据以下规则捕获一组文本:

  • 捕获以"and""or"开头并以"or""and"
  • 结尾的行
  • 捕获的行可以有多个括号。
  • 如果运算符"or""and"在括号中,则忽略它们

从上面的字符串中,我期待如下所示的结果组

  
      
  • 这里的东西(这里的其他内容(这里有些东西)和其他东西其他东西)asdf( asdfas)
  •   
  • 和这里的东西
  •   
  • 或其他地方(此处还有别的东西或其他东西)
  •   

我尝试了许多正则表达式,并且接近我想要的正则表达式是:

(and|or)\s.((?!(and|or)).)*

我也可以使用非正则表达式解决方案。

2 个答案:

答案 0 :(得分:3)

这是一个工作小提琴http://jsfiddle.net/e8tMb/

(如果您对支持嵌套括号的示例感兴趣,我在此答案的底部添加了一个)

此实现纯RegEx,但是,我认为这是非常容易理解的。它循环遍历字符串,并以非常简单的方式完成您指定的内容。

假设我们有字符串:

var str="and something here ( something else here and something else or something else) and something here or something here ( something else here and something else or something else)";

我们可以根据相关的标点符号tokeninize

var tokens = str.split(/( |\(|\))/g) 

结果是:

["and", " ", "something", " ", "here", " ", "", "(", "", " ", "something", " ", "else", " ", "here", " ", "and", " ", "something", " ", "else", " ", "or", " ", "something", " ", "else", ")", "", " ", "and", " ", "something", " ", "here", " ", "or", " ", "something", " ", "here", " ", "", "(", "", " ", "something", " ", "else", " ", "here", " ", "and", " ", "something", " ", "else", " ", "or", " ", "something", " ", "else", ")", ""]

现在,我们可以迭代这些令牌并简单地检查句子: var str =“和这里的东西(这里有别的东西,别的东西或别的什么东西)和这里的东西或其他的东西(这里有别的东西和别的东西)”;

var tokens = str.split(/( |\(|\))/g);

var inParans = false;
var sentences = [];
var lastIndex = 0;
for(var i=0;i<tokens.length;i++){
    if(tokens[i] === "("){
        inParans = true;
    } else
    if(tokens[i] === ")"){
        inParans = false;
    } else
    if((tokens[i] === "and" || tokens[i] === "or") && !inParans){
        sentences.push(tokens.slice(lastIndex,i).join("")); // add sentence
        lastIndex = i;
    }
}
sentences.push(tokens.slice(lastIndex).join(""));

document.body.innerHTML = (sentences.join("<br />"));

如果您想匹配嵌套的parans

小提琴http://jsfiddle.net/UbeS8/

在CS理论中使用正则表达式,由于the pumping lemma(它们没有内存),因此不可能匹配嵌套数据。但是,使用我们的标记化器,因为我们没有开始使用RegExp,添加这种东西很容易,我们只计算括号。与正则表达式(严格意义上没有记忆)不同,我们可以使用变量轻松跟踪。这是代码:

var tokens = str.split(/( |\(|\))/g);

var inParans = 0;
var sentences = [];
var lastIndex = 0;
for(var i=0;i<tokens.length;i++){
    if(tokens[i] === "("){
        inParans++;
    } else
    if(tokens[i] === ")"){
        inParans--;
        if(inParans < 0){ //invalid syntax
            throw new Error("Invalid syntax");
        }
        //If you don't want this to be an error, you can do what Scott suggested and do
        //            inParans = Math.max(inParans - 1, 0);
    } else
    if((tokens[i] === "and" || tokens[i] === "or") && (inParans===0)){ // no nesting added check
        sentences.push(tokens.slice(lastIndex,i).join("")); // add sentence
        lastIndex = i;
    }
}
sentences.push(tokens.slice(lastIndex).join(""));

document.body.innerHTML = (sentences.join("<br />"));

答案 1 :(得分:2)

这个应该符合您的需求(demo):

\b(?:and|or)\b((?:[(][^)]+[)]|.)+?)(?=\b(?:and|or)\b|$)

ands / ors之间的数据被捕获在第一组中。