регулярное выражение для атрибутов html, нужно исправить

#php #html #regex #extraction

#php #HTML #регулярное выражение #извлечь

Вопрос:

Нужно исправить это регулярное выражение, которое извлекает атрибуты html в массив для меня с помощью функции preg_mach_all в php:

(S )=["']?((?:.(?!["']?s (?:S )=|[>"'])) .)["']?

примером атрибутов является:

 style="width: 462px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAg4AAALoCAYAAAAQpn2mAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dv4AACAASURBVHic7L15fNTVufj/PjOTyWSyTfaEJBD2EJBNQFQEtFVRXMD7VQG1dfu2tLW92t77unaxam t9nbTXze9tW61Vdqvgre9FXcqUHFBFiUEkX0PgSQkmf1zzu Pzz6ZhBBwg3l4kZn5fM7yPM8553me85znnAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAqIiy66SDXM/SW7DyUQgEIBAiFAKTOZQn8p7N/OQhB6PgFCgUI43ull6mmwyhUolFWJMB.......=" data-filename="Screenshot from 2016-02-09 21:54:47.png"
  

рабочий пример в finddle: https://regex101.com/r/QE9XGD/1

из-за знака равенства в конце src атрибута я получил неправильный массив:

  Array
(
    [0] => Array
        (
            [0] => style="width: 462px;"
            [1] => src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAg4AAALoCAYAAAAQpn2mAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dv4AACAASURBVHic7L15fNTVufj/PjOTyWSyTfaEJBD2EJBNQFQEtFVRXMD7VQG1dfu2tLW92t77unaxam t9nbTXze9tW61Vdqvgre9FXcqUHFBFiUEkX0PgSQkmf1zzu Pzz6ZhBBwg3l4kZn5fM7yPM8553me85znnAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAqIiy66SDXM/SW7DyUQgEIBAiFAKTOZQn8p7N/OQhB6PgFCgUI43ull6mmwyhUolFWJMB.......=" data-filename="
        )

    [1] => Array
        (
            [0] => style
            [1] => src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAg4AAALoCAYAAAAQpn2mAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dv4AACAASURBVHic7L15fNTVufj/PjOTyWSyTfaEJBD2EJBNQFQEtFVRXMD7VQG1dfu2tLW92t77unaxam t9nbTXze9tW61Vdqvgre9FXcqUHFBFiUEkX0PgSQkmf1zzu Pzz6ZhBBwg3l4kZn5fM7yPM8553me85znnAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAqIiy66SDXM/SW7DyUQgEIBAiFAKTOZQn8p7N/OQhB6PgFCgUI43ull6mmwyhUolFWJMB.......
        )

    [2] => Array
        (
            [0] => width: 462px;
            [1] =>  data-filename=
        )

)
  

правильный массив должен быть таким:

 Array
    (
        [0] => Array
            (
                [0] => style="width: 462px;"
                [1] => src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAg4AAALoCAYAAAAQpn2mAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dv4AACAASURBVHic7L15fNTVufj/PjOTyWSyTfaEJBD2EJBNQFQEtFVRXMD7VQG1dfu2tLW92t77unaxam t9nbTXze9tW61Vdqvgre9FXcqUHFBFiUEkX0PgSQkmf1zzu Pzz6ZhBBwg3l4kZn5fM7yPM8553me85znnAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAqIiy66SDXM/SW7DyUQgEIBAiFAKTOZQn8p7N/OQhB6PgFCgUI43ull6mmwyhUolFWJMB.......="
               [2] => data-filename="Screenshot from 2016-02-09 1:54:47.png"
            )

        [1] => Array
            (
                [0] => style
                [1] => src
                [2] => data-filename
            )

        [2] => Array
            (
                [0] => width: 462px;
                [1] => data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAg4AAALoCAYAAAAQpn2mAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dv4AACAASURBVHic7L15fNTVufj/PjOTyWSyTfaEJBD2EJBNQFQEtFVRXMD7VQG1dfu2tLW92t77unaxam t9nbTXze9tW61Vdqvgre9FXcqUHFBFiUEkX0PgSQkmf1zzu Pzz6ZhBBwg3l4kZn5fM7yPM8553me85znnAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAYykIEMZCADGchABjKQgQxkIAMZyEAGMpCBDGQgAxnIQAqIiy66SDXM/SW7DyUQgEIBAiFAKTOZQn8p7N/OQhB6PgFCgUI43ull6mmwyhUolFWJMB.......=
                [2] => Screenshot from 2016-02-09 1:54:47.png
            )

    )
  

как исправить это регулярное выражение, чтобы получить правильный ответ?

Помните, что я использую это регулярное выражение не только для извлечения атрибутов изображения, это универсальное регулярное выражение для всех типов html-тегов

Комментарии:

1. А как насчет DOM способа вместо этого???

2. Регулярное выражение быстрее, поэтому требуется решение regex, если это возможно

Ответ №1:

(S ?)=["']?((?:.(?!["']?s (?:S )=|[>"'])) .)["']?

Изменение заключается в том, чтобы сделать оценку имени атрибута ленивой, поэтому она выполняется только до тех пор, пока не найдет = .

Рабочий пример для regex101

При этом я вполне уверен, что это регулярное выражение может быть уменьшено.


([^s=] )=('?)("?)([^>"']*)23 вероятно, это лучший вариант:

Это занимает около 2% времени отложенной оценки и будет использовать атрибуты как с одиночными, так и с двойными кавычками. Большое изменение здесь заключается в том, что группы захвата, которые вы хотите, являются 1-й и 4-й. Насколько я знаю, это будет работать на любом html, кроме: tag='"value'

регулярное выражение 101

Комментарии:

1. Я изо всех сил пытаюсь получить правильное регулярное выражение, и в какой-то момент я подумал, что это, возможно, мой шанс сделать это правильно. Но, к сожалению, это не работает с title="What about simple quotes like ' in my title attribute?" . Вы также должны добавить необязательные пробелы вокруг, = поскольку class = stupid-spaces это допустимый HTML, точно так же, как data-something = 'also stupid spaces' . В настоящее время у меня есть это регулярное выражение: b(?<attr>w )s*=s*(?<delim>["']|b)(?<value>.*?)k<delim> . Но это не работает без значений в кавычках, и я не могу найти решение:-(