Какие арифметические выражения в ZSH могут отображаться в качестве нижнего индекса массива?

Использование синтаксического анализатора XML — действительно хорошая идея, но если вы не можете его использовать по какой-либо причине, (файл неправильно -сформирован, у вас не установлены какие-либо синтаксические анализаторы и т. д. )], вы можете использовать для этого PERL:

$ perl -ne 'if(/<h2>(.*?)<\/h2><p>(.*?)<\/p>/){print "$1\t$2\n"}' filename.ext
Hello   World
Bells   Walls
Jelly   Minus

Я предпочитаю использовать ленивые совпадения, чтобы не получить непредвиденных результатов:

test.txt

<h1>Nothing</h1>
<h2>Hello</h2><p>World</p><h2>Goodbye</h2><p>Earth</p>
<h2>Bells</h2><p>Walls</p>
<h2>Jelly</h2><p>Minus</p>
<h3>Zip</h3>

$ perl -ne 'if(/<h2>(.*?)<\/h2><p>(.*?)<\/p>/){print "$1\t$2\n"}' test.txt
Hello   World
Bells   Walls
Jelly   Minus
$ perl -ne 'if(/<h2>(.*)<\/h2><p>(.*)<\/p>/){print "$1\t$2\n"}' test.txt
Hello</h2><p>World</p><h2>Goodbye       Earth
Bells   Walls
Jelly   Minus

Как вы можете видеть, только использование регулярного выражения не позволит получить все случаи, которые можно получить с помощью инструмента, специфичного для предметной области -. Если вы согласны с этим, то все в порядке; просто имейте в виду, что вы можете получить неточные результаты, если ввод не соответствует точно вашему шаблону!

4
21.12.2020, 23:52
1 ответ

Технически любое выражение может отображаться как индекс. Проблема заключается в том, чтобы парсер поместил то, что вы хотите, в индекс. Некоторые символы, в том числе пробелы, никогда не появляются. Только символы, составляющие слово, могут быть частью нижнего индекса, потому что нижний индекс является частью слова.

mc% echo $arr[ 1]       
zsh: invalid subscript
mc% echo $arr[1 ]
zsh: invalid subscript
mc% echo $arr[$#arr - 1]
zsh: invalid subscript
mc% echo $arr[$#arr-1]
d

Синтаксический анализатор нижнего индекса останавливается на первом недопустимом символе, и ошибка «недопустимый нижний индекс» возникает еще до того, как zsh проверит завершающую закрывающую скобку.

mc% echo $arr[ 1  
zsh: invalid subscript

В echo $arr[ 1]часть после пробела фактически считается отдельным словом.:echoполучит два аргумента, являющихся результатом расширения $arr[и 1], за исключением того, что zsh не начинает выполнение какой-либо команды из-за к сбою разбора.Есть несколько случаев, когда вы можете сказать, что то, что вы можете представить как часть арифметического выражения, на самом деле не анализируется как таковое, например:

mc% echo $arr[1<<2]   
heredoc> << is a heredoc operator, not part of the subscript.
heredoc> 2]
zsh: invalid subscript

Символы, не составляющие -слова -, могут, конечно, проникать как часть вложенного расширения, такого как арифметическое выражение или подстановка команды.

mc% echo $arr[$[1&3]] 
a
mc% echo $arr[`echo "1 + 2"`]  
c

Если расширение параметра заключено в двойные кавычки, любой символ (, кроме сбалансированной закрывающей скобки или концевой кавычки ), проходит через индекс и становится частью нижнего индекса. Это потому, что внутри двойных кавычек любой символ фактически является символом, составляющим слово. Аналогичным образом, если расширение параметра использует фигурные скобки, zsh ищет закрывающую фигурную скобку }для раскрытия параметра, прежде чем искать закрывающую скобку ]для нижнего индекса, и поэтому символы, не составляющие -слова -, делают его в нижний индекс.

mc% echo "$arr[$#arr - 1]"
d
mc% echo ${arr[$#arr - 1]}
d

Если вы хотите углубиться в мельчайшие -детали, соответствующая функцияparse_subscriptвызывается изgetindex.

5
18.03.2021, 22:41

Теги

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