Если вы хотите переопределить границы слов для своих нужд, вам нужно перечислить их. Один из подходов состоит в том, чтобы взять шаблон границы и добавить его в конце:
echo "well #menu not #menu-foo #menu" | sed -r 's/#menu([ \t\n\r.!?,]|$)/#MENU\1/g'
well #MENU not #menu-foo #MENU
|$
- захватить конец файла / конец регистра ввода.
Я до сих пор не знаю роли ведущего #, но, думаю, вы можете применить эту идею до сих пор, если вам нужно что-то вроде \ 1MENU \ 2 для первого шаблона разделителя.
обновление 28.07, 23: 45:
- равно (пусто / табуляция до и после шаблона $)
[ \t]pattern[ \t]
- равно (пробел / табуляция перед шаблоном $), затем точка плюс все что угодно (# pattern.whwhat)
[ \t]pattern.[^ \t]
исчерпывающее описание «что угодно» было бы лучше. Допустимы дополнительные точки - как мы можем распознать, что «все» закончилось? Пробелы
- равно (пусто / табуляция непосредственно перед шаблоном $), затем # плюс все что угодно (# образец # все что угодно)
[ \t]pattern#[^ \t]
хорошо, это то же самое, что и выше, просто хэш вместо точки.
- как у шаблона # what.pattern или # what # (пробел / табуляция перед #whither и после #pattern).
[ \t]#[^ \t].pattern[ \t]
или
[ \t]#[^ \t]#pattern[ \t]
Нет. 2 и 3 почти одинаковы. Если мы имеем в виду A или B, мы можем просто сформировать группу [#.]. Внутри группы нам не нужно маскировать точку, потому что точка как джокер не имеет никакого смысла в группе.
Нет. Таким образом, 2 и 3 вместе взятых
[ \t]pattern[#.][^ \t][ \t]
Но! Вы ничего не делаете с «чем угодно». Что бы это ни было, оно не изменилось. Итак, мы добавляем # и. просто к списку разделителей (пробел и табуляция) и вернуть их (или пробел или табуляцию), какими бы они ни были:
[ \t]pattern([#. \t])
Простой тест:
echo "well #menu not #menu-false #menu.dot #menu#hash" \
| sed -r 's/[ \t]#menu([#. \t])/ #MENU\1/g'
well #MENU not #menu-false #MENU.dot #MENU#hash
Это изменило бы объект перед #Menu, будь то пустым или табуляцией, всегда пустым. Мы могли бы захватить это тоже, если хотели.
| sed -r 's/([ \t])#menu([#. \t])/\1#MENU\2/g'
Но как насчет последнего правила, номера 4, где «что угодно» ведет «образец»? Мы можем объединить точку и хэш:
[ \t]#[^ \t][.#]menu[ \t]
Объединение этого случая в нашем регулярном выражении позволило бы # foo # pattern # bar. Это становится сложным. Нам лучше начать новую, новую команду:
s/([ \t]#[^ \t]+[.#])menu[ \t]/\1MENU /g'
, к которому можно добавить ';' после предыдущего:
| sed -r 's/[ \t]#menu([#. \t])/ #MENU\1/g;s/([ \t]#[^ \t]+[.#])menu[ \t]/\1MENU /g'
Так что, я думаю, я решил ваши 4 правила, но пример вверху касается только двух из них. И ваша попытка снова включает \<
и \>
, что только сбивает с толку.
Вот мой самодельный пример, включая случай для правила 4:
echo "well #bar.menu and #foo#menu #menu not #menu-false #menu.dot #menu#hash" \
| sed -r 's/[ \t]#menu([#. \t])/ #MENU\1/g;s/([ \t]#[^ \t]+[#.])menu[ \t]/\1MENU /g'
well #bar.MENU and #foo#MENU #MENU not #menu-false #MENU.dot #MENU#hash