подстроки и regexps

Канонический ответ на этот вопрос: С сотрудничеством процесса любым механизмом это обеспечивает. Без сотрудничества процесса это невозможно. То, что процесс состоит из потоков, является внутренней деталью процесса то есть, намеренным дизайном, не выставленным за пределами процесса.

5
07.04.2011, 03:27
2 ответа

Ваш getsubstr $var0 передает 5 args функции.
Кроме того, $* и $ тестируют каждый отдельный $1$ 2 и т.д. аргумент против # шаблона.

Оценка RegEx в bash: Я добавил некоторые примеры в конце, и btw, '*' является только специальным regex символом, когда он используется в regex контексте, т.е. при использовании = ~. В Вашем первом использовании * в ${*, специальное использование звездочки как (psuedo) название var, который расширяется до конкатенации всего Вара: $ за $1$ 2... и т.д...
Ваше второе использование звездочки, в #*"${2}", означает, что "2$", которым что-либо предшествует включая ничто, должны быть подобраны против каждого, передал 1$ и т.д. аргумент отдельно/индивидуально.

Следующий сценарий может помочь с $ и $* (примером)...

#!/bin/bash
#   
getsubstr() {
  echo -n " ${#@} args";
  [[ "$1$2$3$4$5$6" == *\ * ]] && echo " (with embedded spaces)" || echo " (no spaces)"
  echo '                  "${*}"          '\|"${*}"\|
  echo '                   ${*}           '\|${*}\|
  echo '                  "${@}"          '\|"${@}"\|
  echo '                   ${@}           '\|${@}\|
  echo '                  "${*#*"${2}}"   '\|"${*#*"${2}"}"\|
  echo '                   ${*#*"${2}}    '\|${*#*"${2}"}\|
  echo '                  "${@#*"${2}}"   '\|"${@#*"${2}"}"\|
  echo '                   ${@#*"${2}}    '\|${@#*"${2}"}\|
  echo '                        ${*#B}    '\|${*#B}\|
  echo '                       "${*#B}"   '\|"${*#B}"\|
  echo '                        ${@#B}    '\|${@#B}\|
  echo '                       "${@#B}"   '\|"${@#B}"\|
}
var0="a B c      "
echo
echo -n "Passing "; getsubstr "$var0" ; echo
echo -n "Passing "; getsubstr  $var0  ; echo
echo -n "Passing "; getsubstr "$var0" "$var0" ; echo
echo -n "Passing "; getsubstr  $var0   $var0  ; echo
echo
exit 
###################################################################

RegEx в bash

# Regex checks: "=~" uses extended regular expression
#+  Parenthesized subexpressions within the regular expression are saved
#+  in the array variable BASH_REMATCH
#+  $BASH_REMATCH / ${BASH_REMATCH[0]} is the string matching the entire regular expression. 
#+  ${BASH_REMATCH[n]} is the sub string matching the nth parenthesized subexpression

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# $BASH_REMATCH"
# abc

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[0]}"
# abc

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[2]}"
# b

  [[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[@]}"
# abc a b c

6
27.01.2020, 20:35
  • 1
    Большое спасибо. Ваш ответ информативен и (мне) завершенный. Я особенно ценю Ваши примеры. –  bev 09.04.2011, 06:34

Обновление с объяснением

Причина Вы видите этот тип поведения, состоит в том потому что $* или даже $@ расширяется до всех позиционных параметров: $1, $2 и т.д. Когда Вы пытаетесь сделать Расширение параметра (PE) на любом из тех двух специальный Вар, Вы применяете PE к каждому позиционному параметру и ни одной строке.

Выборка от man bash

$ {parameter#word}
Удалите соответствие шаблону префикса. Слово расширено для создания шаблона так же, как в расширении пути. Если шаблон соответствует началу значения параметра, то результатом расширения является расширенное значение параметра с самым коротким шаблоном соответствия ( #'' case) or the longest matching pattern (the##'' случай) удаленный. Если параметр или *, операция удаления шаблона применяется к каждому позиционному параметру в свою очередь, и расширение является результирующим списком.

По существу то, что Вы делаете, является этим:

getsubstr() { 
  tmp=$2
  for arg; do 
    printf "%s " ${1#*$tmp}
    shift
  done
}

Следующая функция работает путем установки $* к временному var $tmp потому что Вы теперь применяете PE к нормальной переменной однажды.

getsubstr() {
  tmp=$*
  echo ${tmp#*$2}
}

P.S.

Не использовать function поскольку это не POSIX и на самом деле абсолютно ненужный, если Вы уже используете () после Вашего имени функции.

P.P.S

Это на самом деле не имеет никакого отношения к регулярным выражениям, а скорее шаровидным выражениям. Более официально они известны как Расширения Параметра

4
27.01.2020, 20:35
  • 1
    благодарит за Ваш ответ и дополнительную информацию. Я навел справки о больше на различии между регулярными выражениями и шаровидными выражениями и подошел пробел. Можно ли расшириться немного на том, что отличило каждого?Спасибо. перенос –  bev 09.04.2011, 06:13
  • 2
    @bev смотрит на термин 'подстановочный знак', он совпадает с шаровидными выражениями. спасибо вам обоим –  SiegeX 09.04.2011, 11:37
  • 3
    Этот сайт (dartmouth.edu/~rc/classes/ksh/print_pages.shtml) говорит: "Подстановочные знаки не являются полными регулярными выражениями. Sed, grep, awk и т.д. работают с более гибким (и более сложный) операторы сопоставления строк". который, кажется, подразумевает, что подстановочные знаки являются подмножеством полного набора regexps, т.е. являются регулярными выражениями, но ограниченный в количестве их, а также команды, которые используют их. Вы согласились бы с этим? –  bev 11.04.2011, 05:17
  • 4
    я не являюсь трудным. Я просто хочу понять, являются ли подстановочные знаки и regexps отличающимися натуральный или просто тот же вид вещи, но в контексте удара, используемого при различных обстоятельствах. Например, в исходном коде для удара, подстановочные знаки реализованы с помощью regexps? –  bev 11.04.2011, 05:18
  • 5
    @bev: Хотя функционально эквивалентное регулярное выражение может быть сделано соответствовать регулярному выражению шаровидного выражения, реверс не верен. Шарики не являются регулярным языком и следовательно не регулярным выражением. –  SiegeX 11.04.2011, 07:52

Теги

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