Как мне улучшить мое регулярное выражение до grep домена третьего уровня, но, наконец, без дополнительного символа?

#regex #bash #awk #grep #subdomain

#регулярное выражение #bash #awk #grep #поддомен

Вопрос:

Это регулярное выражение greps все. Как я могу отображать только домен, но не дополнительные символы.

 echo "AAAA  cccc.google.com BBBB" | grep -oE "[^.n]*((.[^.n]*){2}$)"  --color=always 
  

Я хочу cccc.google.com , чтобы меня проверили, но нет AAAA cccc.google.com BBBB . Добавление b не работает.
echo "AAAA cccc.google.com BBBB" | grep -oE "b[^.n]*((.[^.n]*){2}b$)b" --color=always

Редактировать: я забыл сказать, что мне нужно было для grepping доменов третьего и четвертого уровней. Вот что я имел в виду:

  • g.google.com Это домен третьего уровня
  • a.b.google.com Это домен 4-го уровня.

Мое приведенное выше регулярное выражение отображало домен третьего уровня, но оно отображало какой-то другой символ, поэтому я задал вопрос. Допустим, у меня есть AAAA a.b.c.d.e.g.google.com BBBB , тогда {3} должен дать мне g.google.com и {4} или {3,4} должны дать мне e.g.google.com в то же время опуская некоторые нежелательные символы. Мое регулярное выражение делает именно это, но есть дополнительный символ!

Итак, используя это регулярное выражение (из ответа, изменено):
echo "AAAA d.cccc.google.com BBB" | grep -oE 'w (.w ){2}'
опускает часть .com, которой нет в моем регулярном выражении (но оно печатает extra char : ( ). Итак, не могли бы вы изменить, чтобы работать в этом случае.

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

1. echo "AAAA cccc.google.com BBBB" | awk '$0=$2'

2. Поскольку я создаю это регулярное выражение для gf (tomnomnom’s gf, оно здесь не пригодится)

Ответ №1:

Похоже, OP хочет интерактивное регулярное выражение (уточняется в комментариях), которое может извлекать n количество доменов, где n является переменной.

Что-то вроде этого должно работать- (?:w (?:.|b)){4}(?=.w (?: |$)).w

Посмотрите демонстрацию

Использование

  • С {2}

     $ echo "AAAA  a.b.c.d.e.g.google.com BBB" | grep -oP "(?:w (?:.|b)){2}(?=.w (?: |$)).w "
    g.google.com
      

    Захватывает 2 поддомена, исключая домен верхнего уровня (т.е. com )

  • С {3}

     $ echo "AAAA  a.b.c.d.e.g.google.com BBB" | grep -oP "(?:w (?:.|b)){3}(?=.w (?: |$)).w "
    e.g.google.com
      

    Захватывает 3 поддомена, исключая домен верхнего уровня (т.е. com )

…и так далее

Объяснение

(?:w (?:.|b)){3} <- Это то же самое, что и мои оригинальные ответы, он просто фиксирует символы слова, за которыми следует a . , ровно 3 раза

(?=.w (?: |$)).w <- Это действует как точка остановки предыдущего регулярного выражения. Оно отмечает начало домена верхнего уровня и фиксирует его.

Оригинальный ответ

Это регулярное выражение кажется совершенно неправильным, если вы хотите сопоставлять только такие URL, как cccc.google.com и www.google.com , но не google.com , вы должны использовать- (?:w (?:.|b)){3}

Посмотрите демонстрацию

Объяснение

Основная часть w (?:.|b) — это совпадение символов слов, за которыми сразу следует a . или граница слова (т.е. Пробел)

Это прилагается к a (?:){3} , который гарантирует, что такие группы встречаются 3 раза.

Чтобы также отображать домены 4-го уровня, просто измените значение {3} на {3,4}

(?:w (?:.|b)){3,4}

Посмотрите демонстрацию

Вот как вы должны это сделать с grep

 $ echo "AAAA  cccc.google.com BBB" | grep -oP "(?:w (?:.|b)){3,4}"
cccc.google.com
  

И с d.cccc.google.com

 $ echo "AAAA  d.cccc.google.com BBB" | grep -oP "(?:w (?:.|b)){3,4}"
d.cccc.google.com
  

Ответ №2:

echo "AAAA cccc.google.com BBBB" | grep -oE 'w (.w ) ' --color=always Похоже, это работает. w это более или менее то, что следует ожидать от доменных имен.