ZSH Equivalent «EXPR» ZPR «ABCDEFGHIJKLMNOPQRSTUVWXYZ» XYZD`

Вы не можете включить ] в класс символов путем обратного слэширования. Он должен быть первым элементом в классе. То же самое относится и к тире, но на этот раз оно должно быть последним. \-\^ просто соответствует диапазону от \ до \, т.е. обратной косой черты и каретки. (Я также удалил бесполезные обратные слеши).

regex='^[]0-9a-zA-Z,!^`@{}=().;/~_|[-]*$'

Вы уверены, что вам нужно *, а не +? Вы действительно хотите принимать пустые строки?

1
31.07.2018, 08:34
3 ответа

Если вы ищете zshвстроенную альтернативу этому не -стандартному exprиспользованию (, ничего общего с bashмежду прочим ), вы можете:

$ a=abcdefghijklmnopqrstuvwxyz b=xyzd
$ echo ${a[(i)[$b]]}
4

С помощью iвы получаете индекс первого совпадения (или единицу плюс длину стога сена, если совпадения нет ). Вместо этого с Iвы получите последнее совпадение (или 0, если совпадения нет ).

С любой оболочкой, подобной POSIX -(, включая bashиzsh)

$ s=${a%%[$b]*}
$ echo "$(($#s + 1))"
4
4
27.01.2020, 23:12

Реализация expr, найденная в пакете GNU coreutils, является внешней утилитой и может использоваться одинаково независимо от того, какую оболочку вы используете.

В zsh,

expr index "abcdefghijklmnopqrstuvwxyz" xyzd

вернет 4, как в bashили любой другой оболочке.

Операция indexв GNU exprявляется расширением стандарта expr, что означает, что вы, скорее всего, получите ошибку expr: syntax errorв системах без этой конкретной реализации expr. Это независимо от того, какую оболочку вы используете.

3
27.01.2020, 23:12

Как уже указал Кусалананда в своем комментарии, вы, конечно, можете использовать exprи в zsh, но я думаю, вы имели в виду, есть ли в Zsh встроенный способ сделать это.

Ответ "нет", но в нем есть что-то похожее:

v="abcdefghijklmnopqrstuvwxyz"
i=${(SB)v#cdef}

Это установит iна 3. Однако есть две причины, по которым это не работает точно так же, какexpr index:

В приведенном вами примере вы ищете xyzd , которого нет в вашей строке, но поскольку ваша строка заканчивается на xyz , exprизящно удаляет ' d' и возвращает совпадение. Можно возразить, что поведение Zsh в этом отношении более разумно, но, конечно, если это важный вопрос для вас, я бы остановился на Zsh.

Другая причина, по которой Zsh отличается, заключается в том, что ${(SB)v#...}возвращает 1, если строка не соответствует не . Например,

echo ${(SB)v#a}
echo ${(SB)v#7}
Оба

вернут 1. Только с этим вы не сможете отличить совпадение, отличное от -, и совпадение по первому символу. Одним из возможных решений является вычисление положения и длины совпадения :

.
# N returns the length of the match
index_and_length=${(SBN)v#...}
# index_and_length contains the index, a space, and the length
if [[ ${index_and_length#* } == 0 ]]
then
  echo no match
else
  index=${index_and_length% *}
  echo match at index $index
fi

ОБНОВЛЕНИЕ :Как показывают комментарии к этому сообщению, я неправильно понял цель expr index; следовательно, мой ответ в том виде, в каком он дан, неадекватен. Однако мы можем адаптировать его, потому что искомая "строка" представляет собой шаблон глобуса -. Следовательно, квадратные скобки сделают эту работу :

.
# Search for the first occurance of one of the letters x y z d
index_and_length=${(SBN)v#[xyzd]}
0
27.01.2020, 23:12

Теги

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