Regex: Как я могу удалить пробелы только в атрибуте стиля? - PullRequest
1 голос
/ 14 сентября 2010

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

В основном у меня html-документ электронной почты, который имеет много атрибутов style для встроенного оформления элементов, которые выглядят примерно как

<th rowspan="10" style="font-weight: normal; vertical-align: top; text-align: left;" width="87">

Теперь мне нужно удалить все пустое пространство, чтобы оно стало:

<th rowspan="10" style="font-weight:normal;vertical-align:top;text-align:left;" width="87">

Играя в http://www.gskinner.com/RegExr/ Я нашел это поисковое выражение

/style="([\w ;:\-0-9]+)"/gi

, который соответствует только атрибуту style с содержимым, но я не могу понять, как заменить пробел только в пределах группы захвата $ 1.

В конечном счете, я выполню это для поиска и замены всего проекта в TextMate в случае, если это имеет значение.

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

Большое спасибо за чтение,

Jannis

Ответы [ 2 ]

3 голосов
/ 14 сентября 2010

Остерегайтесь стенографических свойств.Например, в

style="background: #fff; border: 1px solid #ccc"

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

((?:\sstyle="|(?!\A)\G))\s*+([a-z]++(?>-[a-z]+)*+)\s*+:\s*+([^;]+?)\s*+;

Заменить на:

$1$2:$3;

Тестируя его в EditPad Pro, он преобразует это (353 символа):

<th rowspan="10" style="font-weight: normal; vertical-align: top; text-align: left;" width="87"><input title="Search" value="" size=57 style="background: #fff; border: 1px solid #ccc ; border-bottom-color: #999; border-right-color:#999;color: #000; font: 18px arial,sans-serif bold; height: 25px; margin: 0; padding: 5px 8px 0 6px; vertical-align: top">

... в это (330 символов):

<th rowspan="10" style="font-weight:normal;vertical-align:top;text-align:left;" width="87"><input title="Search" value="" size=57 style="background:#fff;border:1px solid #ccc;border-bottom-color:#999;border-right-color:#999;color:#000;font:18px arial,sans-serif bold;height:25px;margin:0;padding:5px 8px 0 6px;vertical-align:top">

Но я 'я не рекомендую использовать это или любое другое решение для регулярных выражений;Мне просто любопытно, работает ли он в TextMate так же, как в EditPad.(TextMate использует движок Oniguruma regex, который поддерживает все необходимые функции, поэтому он должен работать, но я сам не могу его проверить.)

Но то, что вы действительно должны использовать для этой работы, этовыделенный CSS-компрессор / минимизатор / минификатор;их там много.

1 голос
/ 14 сентября 2010

Это действительно сложный вопрос.Не удалось найти ни одного регулярного выражения, которое делает это, но вы можете использовать последовательность регулярных выражений для этого:

  1. разбить строки, чтобы style="blabla" появилось в отдельной строке.(пометьте разделенные строки специальными строками, чтобы вы могли вернуться позже).
  2. выполните манипуляции с style="blabla" строками.
  3. воссоедините строки
  4. Очистите оставшиесяспециальные маркеры.

    вот как я это сделал с помощью sed (надеюсь, преобразование в стиль textmate regexp легко):

sed -e 's/\(.*\)\(style="[^"]*"\)\(.*\)/AAA\1\nBBB\2\nCCC\3/g' test.txt | sed '/BBB/s/ //g' | sed -e :a -e '$!N;s/\nBBB//;ta' -e 'P;D' | sed -e :a -e '$!N;s/\nCCC//;ta' -e 'P;D' | sed -e 's/AAA//g'

Пояснение:

sed -e 's/\(.*\)\(style="[^"]*"\)\(.*\)/AAA\1\nBBB\2\nCCC\3/g' test.txt

разбить строки со стилем = "..." на 3 строки и отметить специальными строками AAA, BBB и CCC.это приведет к тому, что файл будет выглядеть следующим образом:

AAA line before style
BBB line with style=""
CCC line after style

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

sed '/BBB/s/ //g'

удаляет пробелы во всех строках, начинающихся с BBB (т.е. линий стиля)

Затем мы воссоединяемся:

sed -e :a -e '$!N;s/\nBBB//;ta' -e 'P;D'

добавляет строки, начинающиеся с BBB, к предыдущим строкам (и удаляет строку BBB)

И затем:

sed -e :a -e '$!N;s/\nCCC//;ta' -e 'P;D'

добавляет строки, начинающиеся с CCC, к предыдущим строкам.

Наконец:

sed -e 's/AAA//g'

удаляет специальную строку AAA.

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

...