1

文字列があり、配列に分割して、角かっこ内にない限り「+」で分割されるようにしたい

たとえば、文字列

"abc+OR+def+OR+(abc+AND+def)"

になる

["abc", "OR", "def", "OR", "(abc+AND+def)"]

そして文字列

"(abc+AND+cde)+OR+(abc+AND+(cde+AND+fgh))"

になる

["(abc+AND+cde)", "OR", "(abc+AND+(cde+AND+fgh)"]

正規表現を使用してこれを行うことは可能ですか?

4

5 に答える 5

3

これは正規表現で行うことができますが、再帰的な正規表現をサポートする言語 (たとえば、perl や PCRE を備えた任意の言語) でのみ行うことができます。

JavaScript 正規表現は再帰をサポートしていないため、簡単ではありません。ただし、追加のプラグインを使用して XRegExp を使用することは可能です:

http://xregexp.com/plugins/#matchRecursive

また、次の 2 つのリンクも確認してください。

于 2012-08-08T18:36:52.683 に答える
2

正規表現でこれを行うことはできないと思います。編集:シルバーごとに、正規表現を使用できます。
1 つの方法は、文字列を 1 文字ずつ解析することです。すぐにコードを使用して回答を編集します。編集: これはサンプルの実装です (注: テストされていないため、1 つまたは 2 つのバグがある可能性があります):

function parseString (str) {
  var splitStr = [], parentheses = 0, i = 0
  for (var j = 0; j < str.length; j++) {
    if (str[j] == '+' && !parentheses)
      i++
    else if (str[j] == '(')
      parentheses++
    else if (str[j] == ')')
      parentheses--
    else
      splitStr[i] += str[j]
  }
  return splitStr
}
于 2012-08-08T18:32:27.807 に答える
0

この正規表現は、ニーズに合っています。

(?!=\([\w\+]+)\+(?![\w+\+]+\))

実際の動作はこちらでご覧ください。

小さな問題が 1 つあります。JavaScript(?!=...)正規表現パーサーには、否定後読みが実装されていません。

正規表現を学んでいる人のために、ここにウォークスルーがあります:

(?!=\([\w\+]+)否定の後読みです。これは「... が先行しない」という意味です。この場合、先行しないものを探しています(lettersOr+

\+私たちが探しているものです。プラス記号 (エスケープ)

(?![\w+\+]+\))否定先読みです。これは「... が続かない」という意味です。この場合、次が続かないものを探しています。lettersOr+)

于 2012-08-08T18:50:19.863 に答える
0

String オブジェクトの match メソッドを使用してこれを行い、次の正規表現を使用できます。

stringObj.match(/([a-zA-Z]+)|([(]([a-zA-Z]+[+])+[a-zA-Z]+[)])+/gi);
于 2012-08-08T18:41:57.087 に答える
0

この機能はあなたのために働くはずです:

var PARENTH_STRING_PLACE_HOLDER = '__PARSTRINGHOLDER__';

var splitPlusNoParenthesis = function(str){
    //Replace the parenthStrings with the placeholder
    var parenthStrings = getParenthesizedStrings(str);
    for(var i = 0; i < parenthStrings.length; i++){
        str = str.replace(parenthStrings[i], PARENTH_STRING_PLACE_HOLDER);
    }

    //Split on '+'
    var splitString = str.split('+');

    //Replace all placeholders with the actual values
    var parIndex = 0;
    for(var i = 0; i < splitString.length; i++){
        if(splitString[i] === PARENTH_STRING_PLACE_HOLDER){
            splitString[i] = parenthStrings[parIndex++];
        }
    }

    return splitString;
};

var getParenthesizedStrings = function(str){
    var parenthStrings = [];

    for(var startIndex = 0; startIndex < str.length; startIndex++){
        if(str[startIndex] === '('){
            var parenthCount = 1;

            var endIndex = startIndex + 1;
            for(; endIndex < str.length; endIndex++){
                var character = str[endIndex];
                if(character === '('){
                    parenthCount++;
                } else if(character === ')'){
                    parenthCount--;
                }

                if(!parenthCount){
                    parenthStrings.push(str.substring(startIndex, endIndex + 1));
                    break;
                }
            }
            startIndex = endIndex;
        }
    }

    return parenthStrings;
};

ここにテストするフィドルがあります。

于 2012-08-08T19:12:49.417 に答える