Регулярное выражение PCRE для регулярного выражения sed

Прежде всего извините за мой плохой английский. Я немецкий парень.

Приведенный ниже код отлично работает в PHP:

$string = preg_replace('/href="(.*?)(\.|\,)"/i','href="$1"',$string);

Теперь T нужно то же самое для sed. Я думал, что это должно быть:

sed 's/href="(.*?)(\.|\,)"/href="{$\1}"/g' test.htm

Но это дает мне эту ошибку:

sed: -e выражение #1, char 36: неверная ссылка \1 на RHS команды `s'


person Seblon    schedule 18.01.2010    source источник
comment
Что вы пытаетесь сделать с этим регулярным выражением?   -  person Adam Matan    schedule 18.01.2010
comment
Можете ли вы уточнить, что вы пытаетесь сопоставить и заменить? Я не знаю регулярных выражений PHP так же хорошо, как я знаю регулярные выражения Linux.   -  person Chowlett    schedule 18.01.2010
comment
PHP использует Perl-совместимое регулярное выражение (PCRE).   -  person Dyno Fu    schedule 18.01.2010
comment
я пытаюсь заменить неправильные URL-адреса, которые имеют расширение . или , в конце. поэтому ‹a href=blubb.de,› следует заменить на ‹a href=blubb.de  -  person Seblon    schedule 18.01.2010


Ответы (5)


sed не поддерживает нежадное соответствие регулярным выражениям.

person Dyno Fu    schedule 18.01.2010
comment
Пожалуйста, уточните этот вопрос. - person Adam Matan; 18.01.2010
comment
(.*?) ‹--- это жадное совпадение.(со знаком вопроса ? ) - person ghostdog74; 18.01.2010
comment
Итак, если sed не поддерживает нежадное совпадение, оно должно поддерживать жадное совпадение. Что мне не хватает? - person Adam Matan; 18.01.2010
comment
@Adam: OP полагается на нежадное совпадение для работы RE. RE, скорее всего, в конечном итоге будет потреблять символы после конца атрибута href. - person outis; 18.01.2010
comment
perldoc.perl.org/perlre.html#Regular-Expressions проверьте квантификаторы подраздел. - person Dyno Fu; 19.01.2010

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

sed 's/href="\(.*?\)(.|\,)"/href="{$\1}"/g' test.htm
person user231967    schedule 18.01.2010
comment
вы не сказали, что хотите сделать, просто регулярное выражение не удалось :) - person user231967; 18.01.2010

Вы должны экранировать символы выбора блока ( и ) следующим образом.

sed 's/href="\(.*?\)\(.|\,\)"/href="{$\1}"/g' test.htm
person Didier Trosset    schedule 18.01.2010

вот решение, оно не префект, только разберитесь с ситуацией одного лишнего "," или "."


sed -r -e 's/href="([^"]*)([.,]+)"/href="\1"/g' test.htm
person Dyno Fu    schedule 18.01.2010

Если вы хотите сопоставить литерал ".", вам нужно экранировать его или использовать в классе символов. В качестве альтернативы сокращению круглых скобок (что вам нужно сделать с базовыми RE) вы можете использовать параметр -E, чтобы указать sed использовать расширенные RE. Наконец, RE, используемые sed, используют \N для ссылки на подшаблоны, где N — цифра.

sed -E "s/href=([\"'])([^\"']*)[.,]\1/href=\1\2\1/i"

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

man sed и man re_format дадут больше информации о RE, используемых в sed.

person outis    schedule 18.01.2010
comment
В моей версии sed он использует -r для указания расширенных регулярных выражений (которые не требуют экранирования скобок) вместо -E. - person tomlogic; 27.03.2012