Проблема Java Regex - PullRequest
       2

Проблема Java Regex

1 голос
/ 03 августа 2010

Я делаю XMLParser для Java-программы (я знаю, что есть хорошие XMLParsers, но я просто хочу это сделать).

У меня есть метод с именем getAttributeValue (String xmlElement, String attribute)и я использую регулярное выражение, чтобы найти последовательность символов, которые имеют имя атрибута плюс

="any characters that aren't a double quote"

Я могу затем проанализировать содержимое кавычек.К сожалению, у меня проблемы с шаблоном регулярных выражений.Если я использую:

Pattern p = Pattern.compile(attribute + "=\"(.)+\"");

Тогда я получаю строку, начинающуюся с моего имени атрибута, но поскольку есть множество атрибутов и значений, а значение последнего имеет двойные кавычки, я получаю нужную мне строку плюсвсе остальные имена и значения атрибутов примерно так:

attributeOne="contents" attributeTwo="contents2" attributeThree="contents3"

Поэтому я подумал, что мог бы иметь шаблон регулярного выражения вместо "."любой символ символов, будет иметь «любые символы, но не двойные кавычки».Я пробовал:

Pattern p = Pattern.compile(attribute + "=\"(.&&[^\"])+\"");
Pattern p = Pattern.compile(attribute + "=\"(.&&(^\"))+\"");
Pattern p = Pattern.compile(attribute + "=\"([.&&[^\"]]+)\"");

но ни один из них не работает.Буду признателен за любые предложения и комментарии.

Спасибо.

Ответы [ 3 ]

7 голосов
/ 03 августа 2010

Шаблон регулярного выражения для:

="any characters that aren't a double quote"

Is ="[^"]*", который в качестве строкового литерала Java равен "=\"[^\"]*\"".

Конструкция [...] называется класс персонажей ;Например, [aeiou] соответствует одному из строчных гласных.Конструкция [^...] является классом символов с отрицанием ;например, [^aeiou] соответствует одному из всего, кроме строчных гласных (который включает согласные, символы, цифры и т. д.).

Обратите внимание, что этот шаблон не позволяет экранировать " в String (см. ссылку нижедля шаблонов, которые учитывают эту возможность).

Ссылки

Смежные вопросы


О сопоставлении жадных, неохотных и отрицательных классов символов

Чтобы понять, почему ".+"не «работает», как ожидалось, и почему иногда вы видите ".+?" неохотную версию, чтобы попытаться «исправить» эту проблему, рассмотрите следующий пример:

Пример 1: От A до Z

Давайте сравним эти две модели: A.*Z и A.*?Z.

С учетом следующего ввода:

eeeAiiZuuuuAoooZeeee

Шаблоны дают следующие совпадения:

Давайте сначала сосредоточимся на том, чтоA.*Z делает.Когда он соответствует первому A, .*, будучи жадным, сначала пытается найти как можно больше ..

eeeAiiZuuuuAoooZeeee
   \_______________/
    A.* matched, Z can't match

Поскольку Z не совпадает, двигательВозвраты, и .* должны соответствовать одному меньшему .:

eeeAiiZuuuuAoooZeeee
   \______________/
    A.* matched, Z still can't match

Это происходит еще несколько раз, пока, наконец, мы не придем к этому:

eeeAiiZuuuuAoooZeeee
   \__________/
    A.* matched, Z can now match

Сейчас Z может совпадать, поэтому общий шаблон совпадает:

eeeAiiZuuuuAoooZeeee
   \___________/
    A.*Z matched

В отличие от этого, повторение с неохотой в A.*?Z сначала соответствует как можно меньшему количеству ., а затем, при необходимости, принимает больше ..Это объясняет, почему он находит два совпадения во входных данных.

Вот визуальное представление о том, что два шаблона совпали:

eeeAiiZuuuuAoooZeeee
   \__/r   \___/r      r = reluctant
    \____g____/        g = greedy

Пример: альтернатива

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

Шаблон A[^Z]*Z также находит те же два совпадения, что и шаблон A.*?Z для вышеуказанного ввода ( каквидел на ideone.com ).[^Z] - это то, что называется классом отрицательных символов : он соответствует чему угодно, кроме Z.

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

Ссылки


Пример 2: от A до ZZ

Этот пример должен быть иллюстративным: он показывает, как шаблоны классов жадных, неохотных и отрицательных символов по-разному совпадают при одном и том же вводе.

eeAiiZooAuuZZeeeZZfff

Это совпадения для вышеуказанного ввода:

Вот наглядное представление того, что они совпали:

         ___n
        /   \              n = negated character class
eeAiiZooAuuZZeeeZZfff      r = reluctant
  \_________/r   /         g = greedy
   \____________/g

Смежные вопросы

1 голос
/ 03 августа 2010
attribute + "=\"[^\"]*\""

должно работать.Но что делать, если строка, с которой вы сопоставляете, может содержать экранированные кавычки?Ожидаете ли вы необходимости справиться с этим?

В этом случае вы можете использовать

attribute + "=\"(?:\\\\.|[^\"])*\""
1 голос
/ 03 августа 2010

попробуйте это:

attribute + "=\".*?\""

Причина этого: * вместо +, поскольку вы можете иметь пустой атрибут: something=""
*? вместо * чтобы сделать его нежелательным вместо жадного.
учебник по регулярным выражениям при повторении

...