Какое регулярное выражение будет соответствовать этим данным? - PullRequest
0 голосов
/ 23 июня 2009

У меня есть следующее в документе XHTML:

<script type="text/javascript" id="JSBALLOONS">
    function() {
        this.init = function() {
            this.wAPI = new widgetAPI('__BALLOONS__');
            this.getRssFeed();
        };
    }
</script>

Я пытаюсь выбрать все между двумя тегами сценария. id всегда будет JSBALLOONS, если это поможет. Я знаю, как выбрать это, включая теги скрипта, но я не знаю, как выбрать содержимое, исключая теги скрипта Результат регулярного выражения должен быть:

    function() {
        this.init = function() {
            this.wAPI = new widgetAPI('__BALLOONS__');
            this.getRssFeed();
        };
    }

Ответы [ 4 ]

8 голосов
/ 23 июня 2009

(Обновлено сообщение специально для решения Javascript.)

В Javascript ваш код может выглядеть так:

if (data.match(/<script[^>]+id="JSBALLOONS">([\S\s]*?)<\/script>/)) {
    inner_script = RegExp.$1;
}

Эта часть в скобках ([\S\s]*?) сохраняется механизмом регулярных выражений и доступна вам после того, как найдено совпадение. В Javascript вы можете использовать RegExp.$1 для ссылки на соответствующую часть внутри тегов скрипта. Если у вас есть несколько таких групп, окруженных (), вы можете ссылаться на них с помощью RegExp.$2 и т. Д. До RegExp.$9.

Javascript не будет соответствовать символам новой строки по умолчанию, поэтому мы должны использовать ([\S\s]*?) вместо (.*?), что может иметь больше смысла. Просто чтобы быть полным, на других языках это не нужно, если вы используете модификатор s (/.../s).

(Я должен добавить, что регулярные выражения, как правило, очень хрупкие при извлечении контента с HTML-страниц, подобных этому. Возможно, вам лучше использовать инфраструктуру jQuery для извлечения содержимого.)

2 голосов
/ 23 июня 2009

Не пытайтесь использовать регулярные выражения для нерегулярных языков. Правильный путь - использовать синтаксический анализатор XML, соответственно. ДОМ:

document.getElementById("JSBALLOONS")

edit: Что касается вашего комментария, у меня нет опыта работы с JavaScript или jQuery, но после некоторого поиска я думаю, что что-то вроде этого должно работать:

$.ajax({
  type: "GET",
  url: "test.xml",
  dataType: "xml",
  success: function(xml) {
    return $(xml).find("#JSBALLOONS").text();
  }
});

Может ли кто-то более квалифицированный исправить это?

2 голосов
/ 23 июня 2009

Что джентльмен подразумевает под 1 долларом, это «стоимость первой группы захвата». Когда вы заключаете часть вашего регулярного выражения в скобки, он определяет группы захвата. Вы считаете их слева направо. Каждая открывающая скобка начинает новую группу захвата. Они могут быть вложенными.

(Существуют способы определения подвыражений без определения групп захвата - я забыл синтаксис.)

В Perl $ 1 - это магическая переменная, содержащая строку, совпадающую с первой группой захвата, $ 2 - строка, совпадающая со второй, и т. Д. В других языках может потребоваться вызвать метод для возвращенного объекта соответствия, чтобы получить N-ное группа захвата.

Но вернемся к решению Мольфа. Предположим, он сказал использовать вместо этого шаблон:

/<script[^>]+id="JSBALLOONS">(.*)<\/script>/

В этом случае, если у вас есть более одного элемента сценария, этот неправильный шаблон поглотит их все, потому что он жадный, и этот момент стоит объяснить. Этот шаблон будет начинаться с первого открывающего тега, совпадать с его закрывающим тегом, продолжать движение и, наконец, соответствовать последнему. Магия в решении Мольфа - вопросительный знак в (. *?), Который делает его не жадным. Он вернет самую короткую строку, которая соответствует шаблону, следовательно, не поглотит лишние элементы скрипта.

0 голосов
/ 23 июня 2009

Пусть foo будет строкой, содержащей код. Затем вы можете удалить теги с помощью

foo = foo.substring(foo.indexOf('>') + 1, foo.lastIndexOf('<'))
...