Как Bash и Zsh обрабатывают сопоставление в шаблонах и регулярных выражениях?

Я решил проблему. Это была группа безопасности AWS, которая была настроена неправильно и заблокировала вход. правило ip изменено с "с 10.0.3.102" на "с 10.0.3.100". В остальном установка была правильной.

1
14.04.2021, 17:54
1 ответ

Нет, нет гарантии, что именно [a-z]совпадет, и точка.

Ну, в любой другой локали, кроме "C"(, если утилита соответствует POSIX ).

Основная проблема связана с выражением "диапазон" (с использованием-).
Явный список, такой как [abcdefghijklmnopqrstuvwxyz], никогда не даст сбой.


POSIX запрашивает, чтобы a-zбыло в точности abcdefghijklmnopqrstvwxyz, да, но только когда локаль является POSIX по умолчанию, то есть:"C".

Из спецификации POSIX:

In the POSIX locale, a range expression represents the set of collating elements that fall between two elements in the collation sequence, inclusive. In other locales, a range expression has unspecified behavior: strictly conforming applications shall not rely on whether the range expression is valid, or on the set of collating elements matched. A range expression shall be expressed as the starting point and the ending point separated by a ( '-' ).

И даже если POSIX запрашивает конкретное значение для a-z, любое приложение может просто игнорировать POSIX.

Просто показать верхушку айсберга:

Python 2.7 соответствует только ASCII на a-z, но Python 3.0 будет соответствовать многим другим символам Unicode. Раньше Bash соответствовал только ASCII до версии 3.2. Затем было решено сопоставить символы, которые сопоставляют между aи z, которые могут включать A-Y(, обычно не Z), в применяемой локали. Теперь в bash версии 5.0+ диапазон настраивается с помощью опции globasciiranges, которая по умолчанию на , делает a-zнамерением соответствовать в основном символам ASCII.

$ LC_COLLATE=en_GB bash -c 'shopt -u globasciiranges; [[ B == [a-z] ]] && echo yes || echo no'
yes

$ LC_COLLATE=en_GB bash -c 'shopt -s globasciiranges; [[ B == [a-z] ]] && echo yes || echo no'
no

Но даже при активном bash 5.0 и globasciiranges == [a-z]будет соответствовать 2190 символам в локали en _GB.utf -8. Просто чтобы вы поняли,это списокa-разрешенных подобных символов:

a a ͣ ⒜              ⓐ A               Ⓐ 
ᵃ ₐ ᴬ   ă Ă ắ Ắ ằ Ằ ẵ Ẵ ẳ Ẳ ấ Ấ ầ Ầ ẫ Ẫ ẩ Ẩ ǎ Ǎ Å ǻ Ǻ ᷲ ꞛ Ꞛ ǟ Ǟ ȧ Ȧ ǡ Ǡ ą
Ą ā Ā ả Ả ȁ Ȁ ȃ Ȃ ạ Ạ ặ Ặ ậ Ậ ḁ Ḁ ᷓ ꜳ Ꜳ  ℀ ᷔ ᴭ ǽ Ǽ ǣ Ǣ ㏂ ㏟ ᷕ ꜵ Ꜵ ℁ ⅍
ꜷ Ꜷ ㍳ ᷖ ꜹ Ꜹ ꜻ Ꜻ ꜽ Ꜽ ẚ ᴀ ⱥ Ⱥ ᶏ ᴁ ᴂ ᵆ ꬱ ɐ Ɐ ᵄ ɑ ᷧ Ɑ ᵅ ꬰ ᶐ ɒ Ɒ ᶛ ꭤ 

И количество совпадающих символов изменяется на 1368 символов, если тест =~ [a-z]. то есть переход на регулярное выражение изменяет список совпадающих символов.

Однако в локали C(для bash )только 26 букв соответствуют (либо ==, либо=~).

зш

Теперь zsh настроен на сравнение числового значения представления wchar _t тестируемого символа с числовым диапазоном в правой части:

[[ "$c" == [a-z] ]]

Но что это значит?

  1. В ASCII, iso -8859 и UTF -8 это обычно означает, что числовое значение wchar _t является тем же числовым значением, что и чармап.

    а. Мы, программисты, должны уже знать о нумерации ASCII. И нет особой причины, по которой @следует сортировать после #, просто повезло.

    б. В качестве практического примера проблемы с iso -8859 :In iso -8859 -1 и iso -8859 -15 ¾и Ÿимеют одинаковое числовое значение. Как это должно быть решено?

    с. Числовое положение символов в Unicode обычно соответствует положению age . Старые символы обычно имеют меньшее числовое значение, чем новые. A ñ(\u00f1), испанский символ не входит в диапазон символов a-z(\u0061-\u007a). Любой говорящий по-испански сказал бы, что так и должно быть.

    $ LC_ALL=es_ES.UTF-8  zsh -c '[[ ñ == [a-z] ]] && echo yes || echo no'
    no
    

    Но что поразительно, это на немецком языке:

    $ LC_ALL=de_DE.UTF-8  zsh -c '[[ ñ =~ [a-z] ]] && echo yes || echo no'
    yes
    
  2. Но (как и Стефан Шазела, поклонник zsh )сказал:

The other problem is that outside of locales using ASCII, ISO-8859-1 or UTF-8 charmaps, the behaviour varies between system as not all systems implement wchar_t's the same.

In fact, what a wchar means is [compiler dependent][4]:

wchar_t is compiler-dependent and therefore not very portable. Using it for Unicode binds a program to the character model of a compiler. Using it for Unicode binds a program to the character model of a compiler.

  1. И вообще, wchar не нужен для использования Unicode, совсем нет. Так :зачем его использовать? И я использую здесь имя Unicode, означающее все существующие символы .

режим тирады на


Извините, но я должен пожаловаться,Мне нужно вытащить это из моей груди.

Да, полезно (для программистов ), что диапазон a -z означает стабильный и желательно небольшой список символов. Да, список нижних букв ASCII кажется разумным (, хотя и наивным )решением. И да, ситуация с [a -z] соответствующими 2190 символам, которые легко меняются от одной версии к другой, как показано выше, является огромной проблемой для программистов и безопасности разрабатываемых приложений.

Но заставить всех и везде иметь возможность сопоставлять только 26 букв в любой локали (, поскольку теперь цель POSIX установить, что [a -z] будет соответствовать только Строчные буквы ASCII в любой локали )чрезвычайно наивны и чрезмерно упрощают рассматриваемую проблему.

код -страницы

Возникла идея кодировать языки в кодовые -страницы (списки обычно из 256 символов ), одна из первых кодовых -страниц была ASCII (всего из 128 символов ). Это был только американский -английский язык.

Но американский -английский всего 369 миллионов человек , остальной мир, 95% мира, не соответствует этому описанию. Просто распространив его на остальную часть Америки, испанцев -португальцев (, которые составляют более 650 миллионов)части Америки, английский язык составляет лишь 36% Америки.

ASCII был расширен для охвата различных языков. Итак, была страница с кодом -для кириллицы, одна страница с кодом -для иврита, одна с испанским ñ, одна с португальским çи т. д. Но это означало, что вы могли не писать письмо на как на иврите , так и кириллице.

Потом пришла мысль, что 16 бит достаточно. И это работало какое-то время, пока мы не получили 50 000 символов из Китая.Несколько решений пытались впихнуть все эти символы всего в 16 бит. Но это не имело никакой надежды на работу.

Это не сработало, как и "кому когда-нибудь понадобится больше памяти, чем 640 КБ?" не работал.

утф -8

Затем, слава богу, сеть приняла UTF -8, и языки стали намного проще. UTF -8 охватывает все 1.114.112 (и многое другое, если необходимо )возможный код UCS2 Unicode -точки (17 *2^16 )напрямую. Да, только есть 143 859 символов, с Unicode 13.0 было назначено (да со всеми включенными китайскими ).

Давайте разбираться :Языков много!!!

Есть много точек зрения!!!

программисты

Мы, программисты (и я включаем себя в число ), наверняка понравится, что все знали об ASCII и что только 26 букв (за все время )совпадали с [a -я]. Но это не мир, в котором мы живем. Большинство людей (Думаю, что 99,9% населения мира не программисты )не знают об ASCII. Но большинство людей, умеющих читать и писать, имеют некоторое представление о том, что такое словарь. И порядок сопоставления - это в основном порядок словаря.

Я уверен, что словарь в Греции не использует -z в качестве основных статей. Это может повториться для большей части мира.

Нам нужно выйти за пределы 26 букв a-z.

Либо мы примем изменение, либо оно будет навязано нам извне со своими хорошими и плохими последствиями. Нам лучше найти решение.

Я мог подумать об использовании [ascii:a-z]или чего-то подобного только для 26 букв ASCII в любой локали, даже C. Да, это не:обратно совместимо, но мы уже находимся в середине проблемы, проблемы обратной совместимости, [a-z]в bash может быть почти что угодно.

Это позволило бы [french:a-z]например и [greek:a-z]и/или [греческое :α -ω] и ожидать чего-то разумного для пользователей этого языка . И [a-z]останется как диапазон всех языков, который мы уже получаем (да, он обратно совместим ).


режим тирады выключен


2
28.04.2021, 22:52

Теги

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