Как найти слова, которые следуют определенному порядку

Разрешение имен — довольно плохой способ блокирования нежелательного веб-трафика. Список вещей, которые нужно блокировать и не блокировать, постоянно меняется, и иногда вам нужно блокировать по URL, а не только по хосту. Браузерные расширения, такие как AdBlock *и uBlock *, как правило, работают намного лучше. Если вы хотите написать свой собственный список, вы можете написать PAC-файл .

Если вы действительно хотите блокировать запросы на основе доменных имен, делайте это с DNS-прокси, а не с /etc/hosts. /etc/hostsможет делать только отдельные хосты. Dnsmasq — популярный легкий DNS-прокси. Некоторые дистрибутивы настраивают dnsmasq по умолчанию; большинство дистрибутивов имеют его в виде пакета. Чтобы весь домен отображался как локальный с помощью dnsmasq, вы можете использовать следующую строку в/etc/dnsmasq.conf:

address=/co.kr/127.0.0.2

2
24.11.2019, 00:08
3 ответа
#!/bin/sh
pttrn="^$(printf '%s' "$1" | sed -e 's/\(.\)/\1*/g' -e 's/\*/\\+/' -e 's/\*$/\\+/')"'$'
grep "$pttrn" /usr/share/dict/words

Шаблон получается из первого аргумента путем вставки *после каждого символа. Затем первый *заменяется на \+; так и последний *. Дополнительно добавляются ^и $. Ваш пример ввода генерирует следующий шаблон:

^q\+w*e*r*t*y*u*y*t*r*e*s*d*f*t*y*u*i*o*k*n\+$

Этот шаблон является правильным шаблоном для grep. qдолжен появиться хотя бы один раз в начале, nдолжен появиться хотя бы один раз в конце. Каждая буква в середине может появляться ноль или более раз, порядок сохраняется.

Обратите внимание, что скрипт тупой. Если вы предоставите ввод с ., [, ]или около того, вы получите регулярное выражение, выходящее за рамки спецификации. Предоставьте разумный ввод или расширьте сценарий, чтобы проверить его.


Примеры:

$./script1.sh qwertyuytresdftyuiokn
queen
question
$./script1.sh te
tee
$./script1.sh superuser
seer
serer
spur
super
supper
surer
$
5
27.01.2020, 21:50

Вот один из способов приблизиться к этому

Во-первых, отфильтруйте список слов до тех слов, которые начинаются и заканчиваются теми же буквами, что и беспорядок. Например, если беспорядок передается как позиционный параметр$1(и предполагается недавняя оболочка bash)

grep -x "${1:0:1}.*${1:(-1):1}" /usr/share/dict/words

Затем возьмите каждое из этих слов и превратите их в регулярное выражение. -Я не могу придумать "хорошего" способа сделать это, но с помощью GNU sed вы могли бы сделать, например

$ sed -E 's/(.)\1*/+.*\1/2g' <<< "queen"
q+.*u+.*e+.*n

Теперь проверьте мешанину на каждом сгенерированном образце.

Собираем все воедино:

$ cat script1 
#!/bin/bash

wordlist=/usr/share/dict/words

while IFS= read -r word; do 
  grep -qEx "$(sed -E 's/(.)\1*/+.*\1/2g' <<< "$word")" <<< "$1" && printf '%s\n' "$word"
done < <(grep -x "${1:0:1}.*${1:(-1):1}" "$wordlist")

, затем

$./script1 qwertyuytresdftyuiokn
queen
question
3
27.01.2020, 21:50

Вот ещё (пробег вbash)Код pythonгенерирует регулярное выражение и передает его в grep. Затем grepработает с выводом почтенной утилиты look, которая выполняет двоичный поиск, чтобы получить все слова /usr/share/dict/words, начинающиеся с qв примере. Таким образом, grepимеет значительно сокращенный набор слов для поиска

python3 -c 'import sys
arr = list(sys.argv[1])
print(*arr, sep="*")
' $1 | grep -x -f - <(look ${1:0:1})

В качестве альтернативы, решение look+ python3, которое позволяет избежать регулярных выражений

look q |./finder.py "qwertyuytresdftyuiokn"

где finder.pyвыглядит следующим образом:

#!/usr/bin/env python3
import sys
from itertools import groupby

seek_word = sys.argv[1]
for word in sys.stdin:
    orig_word = word.strip()
    word = ''.join(k for k, g in groupby(orig_word)) 
    s_w = iter(seek_word)
    i_word = iter(word)
    if all(c in s_w for c in i_word) and not next(s_w, None):
        print(orig_word)
2
27.01.2020, 21:50

Теги

Похожие вопросы