Регулярное выражение для разбора jQuery-селектороподобной строки - PullRequest
3 голосов
/ 01 марта 2010
text = '#container a.filter(.top).filter(.bottom).filter(.middle)';

regex = /(.*?)\.filter\((.*?)\)/;

matches = text.match(regex);

log(matches);
// matches[1] is '#container a'
//matchss[2] is '.top'

Я ожидаю захватить

matches[1] is '#container a'
matches[2] is '.top'
matches[3] is '.bottom'
matches[4] is '.middle'

Одним из решений было бы разделить строку на # контейнер a и отдохнуть. Затем отдохните и выполните рекурсивный exec, чтобы получить элемент inside ().

Обновление: Я публикую решение, которое действительно работает. Однако я ищу лучшее решение. Не очень нравится идея разделения строки и последующей обработки Вот решение, которое работает.

matches = [];

var text = '#container a.filter(.top).filter(.bottom).filter(.middle)';
var regex = /(.*?)\.filter\((.*?)\)/;
var match = regex.exec(text);
firstPart = text.substring(match.index,match[1].length);
rest = text.substring(matchLength, text.length);

matches.push(firstPart);

regex = /\.filter\((.*?)\)/g;
while ((match = regex.exec(rest)) != null) {
  matches.push(match[1]);
}
log(matches);

В поисках лучшего решения.

Ответы [ 5 ]

5 голосов
/ 01 марта 2010

Это будет соответствовать одному приведенному вами примеру:

<html>
  <body>
    <script type="text/javascript">
      text = '#container a.filter(.top).filter(.bottom).filter(.middle)';
      matches = text.match(/^[^.]*|\.[^.)]*(?=\))/g);
      document.write(matches);
    </script>
  </body>
</html>

, который производит:

#container a,.top,.bottom,.middle 

EDIT

Вот краткое объяснение:

^         # match the beginning of the input
[^.]*     # match any character other than '.' and repeat it zero or more times
          #
|         # OR
          #
\.        # match the character '.'
[^.)]*    # match any character other than '.' and ')' and repeat it zero or more times
(?=       # start positive look ahead
  \)      #   match the character ')'
)         # end positive look ahead

РЕДАКТИРОВАТЬ часть II

Регулярное выражение ищет два типа последовательностей символов:

  1. на один или несколько символов, начиная с начала строки до первого ., регулярное выражение: ^[^.]*
  2. или соответствует последовательности символов, начинающейся с ., за которым следует ноль или более символов, отличных от . и ), \.[^.)]*, но должен иметь ) перед это: (?=\)). Последнее требование приводит к совпадению .filter , а не .
3 голосов
/ 01 марта 2010

Думаю, вам нужно повторить.

var head, filters = [];
text.replace(/^([^.]*)(\..*)$/, function(_, h, rem) {
  head = h;
  rem.replace(/\.filter\(([^)]*)\)/g, function(_, f) {
    filters.push(f);
  });
});
console.log("head: " + head + " filters: " + filters);

Возможность использовать функции в качестве второго аргумента String.replace - одна из моих любимых вещей в Javascript: -)

0 голосов
/ 01 марта 2010

text.split() с регулярным выражением делает свое дело.

var text = '#container a.filter(.top).filter(.bottom).filter(.middle)';
var parts = text.split(/(\.[^.()]+)/);
var matches = [parts[0]];

for (var i = 3; i < parts.length; i += 4) {
    matches.push(parts[i]);
}

console.log(matches);
0 голосов
/ 01 марта 2010
var text = '#container a.filter(.top).filter(.bottom).filter(.middle)';
var result = text.split('.filter');

console.log(result[0]);
console.log(result[1]);
console.log(result[2]);
console.log(result[3]);
0 голосов
/ 01 марта 2010

Вам нужно сделать несколько совпадений несколько раз, начиная с того места, где заканчивается последнее совпадение (см. Пример while в https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/exec):

Если ваше регулярное выражение использует флаг "g", вы можете использовать метод exec несколько раз, чтобы найти последовательные совпадения в одной и той же строке. Когда вы это делаете, поиск начинается с подстроки str, указанной в свойстве регулярного выражения lastIndex. Например, предположим, что у вас есть этот скрипт:

var myRe = /ab*/g;
var str = "abbcdefabh";
var myArray;
while ((myArray = myRe.exec(str)) != null)
{
  var msg = "Found " + myArray[0] + ".  ";
  msg += "Next match starts at " + myRe.lastIndex;
  print(msg);
}

Этот скрипт отображает следующий текст:

Found abb. Next match starts at 3
Found ab. Next match starts at 9

Однако , этот случай будет лучше разрешен с помощью пользовательского парсера. Регулярные выражения не являются эффективным решением этой проблемы, если вы спросите меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...