Разрешить использование символов PosixPrint кроме% \ / #?: и кроме пробелов в начале и конце строки - PullRequest
0 голосов
/ 10 апреля 2019

Так Для этого Allow PosixPrint Characters except , % \ / # ? : условие работает

с этим шаблоном регулярных выражений m/^[^\P{PosixPrint}\/\#\%\?\:\,\\]+$/x

Но для этого:

white-space at the beginning and end but allow in the middle

этот шаблон m/^\b[^\P{PosixPrint}\/\#\%\?\:\,\\]+\b$/x является своего рода рабочим (см. вывод).

Строка не совпадает, если в начале и конце появляются символы, кроме [0-9a-zA-Z].

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $vars = [
    q#1#,
    q#1~`!l#,
    q#11#,
    q#111#,
    q#1 1#,
    q# 11#,
    q#11 #,
    q# 11 #,
    q# 1 1 #,
    q#1`~!@$^&*()-_=+|]}[{;'".><1#,
    q#1`~!@$^&*()-_=1#,
    q#1~`!@$^&*()-_=+|]}[{;'".><#,
    q#~`!@$^&*()-_=+|]}[{;'".><1#,
    q#~`!@$^&*()-_=+|]}[{;'".><#,
];

foreach my $var (@$vars){
    if ( $var =~ m/^\b[^\P{PosixPrint}\/\#\%\?\:\,\\]+\b$/x) {
        print "match:\t\t#$var#\n";
    }
    else{
        print "no match:\t#$var#\n";
    }
}

ВЫХОД:

    match:      #1#
    match:      #1~`!l#
    match:      #11#
    match:      #111#
    match:      #1 1#
    no match:   # 11#
    no match:   #11 #
    no match:   # 11 #
    no match:   # 1 1 #
    match:      #1`~!@$^&*()-_=+|]}[{;'".><1#
    match:      #1`~!@$^&*()-_=1#
    no match:   #1~`!@$^&*()-_=+|]}[{;'".><#
    no match:   #~`!@$^&*()-_=+|]}[{;'".><1#
    no match:   #~`!@$^&*()-_=+|]}[{;'".><#

Ожидаемый ВЫХОД:

    match:      #1#
    match:      #1~`!l#
    match:      #11#
    match:      #111#
    match:      #1 1#
    no match:   # 11#
    no match:   #11 #
    no match:   # 11 #
    no match:   # 1 1 #
    match:      #1`~!@$^&*()-_=+|]}[{;'".><1#
    match:      #1`~!@$^&*()-_=1#
    match:      #1~`!@$^&*()-_=+|]}[{;'".><#
    match:      #~`!@$^&*()-_=+|]}[{;'".><1#
    match:      #~`!@$^&*()-_=+|]}[{;'".><#

Информация:

Perl Version: v5.26.2
Platform: Ubuntu 18.10

Ответы [ 2 ]

3 голосов
/ 10 апреля 2019

\b - это граница слова, это граница между символом слова и несловесным символом.

Начало и конец строки считаются несимвольным символом, поэтому \b в конце или в начале строки будет «совпадать» только в том случае, если в первом (последнем) знаке есть символ слова.

Насколько я понимаю, вы хотите отклонить строки, начинающиеся и / или заканчивающиеся пробелом, используйте:

my $vars = [
    q#1#,
    q#1~`!l#,
    q#11#,
    q#111#,
    q#1 1#,
    q# 11#,
    q#11 #,
    q# 11 #,
    q# 1 1 #,
    q#1`~!@$^&*()-_=+|]}[{;'".><1#,
    q#1`~!@$^&*()-_=1#,
    q#1~`!@$^&*()-_=+|]}[{;'".><#,
    q#~`!@$^&*()-_=+|]}[{;'".><1#,
    q#~`!@$^&*()-_=+|]}[{;'".><#,
];

foreach my $var (@$vars){
    if ( $var =~ m/^(?!\h)[^\P{PosixPrint}\/\#\%\?\:\,\\]+(?<!\h)$/x) {
    #               ^^^^^^                                ^^^^^^^
        print "match:\t\t#$var#\n";
    }
    else{
        print "no match:\t#$var#\n";
    }
}

Где

  • (?!\h) - это негативная перспектива, которая гарантирует, что у нас нет горизонтального пробела в первой позиции
  • (?<!\h) является негативным взглядом сзади, который гарантирует, что у нас нет горизонтального пробела в последней позиции

Выход:

match:      #1#
match:      #1~`!l#
match:      #11#
match:      #111#
match:      #1 1#
no match:   # 11#
no match:   #11 #
no match:   # 11 #
no match:   # 1 1 #
match:      #1`~!@$^&*()-_=+|]}[{;'".><1#
match:      #1`~!@$^&*()-_=1#
match:      #1~`!@$^&*()-_=+|]}[{;'".><#
match:      #~`!@$^&*()-_=+|]}[{;'".><1#
match:      #~`!@$^&*()-_=+|]}[{;'".><#
2 голосов
/ 11 апреля 2019

Ниже приведен шаблон, представленный в предыдущем ответе с несколькими исправлениями:

/
   ^
   (?!\s)
   [^\P{PosixPrint}\\\/\#%?:,]*
   (?<!\s)
   \z
/x

В оптимизации приведено следующее:

/
    ^
    (?: [^\P{PosixPrint}\s\\\/\#%?:,]++
        (?: [^\P{PosixPrint}\S]++
            [^\P{PosixPrint}\s\\\/\#%?:,]++
        )*+
    )?+
    \z
/x

Это считается лучшей практикойуказывать, какие символы разрешены (белый список), а не указывать, какие из них не разрешены (черный список).Последний подход подвержен ошибкам.Следующие действия идентичны приведенному выше решению, но вместо черного списка используйте белый список:

/
    ^
    (?: [a-zA-Z0-9!"\$&'()*+\-.;<=>@[\]^_`{|}~]++
        (?: [ ]++
            [a-zA-Z0-9!"\$&'()*+\-.;<=>@[\]^_`{|}~]++
        )*+
    )?+
    \z
/x

или

/
    ^
    (?: (?&SAFE_CHAR)++
        (?: [ ]++
            (?&SAFE_CHAR)++
        )*+
    )?+
    \z

    (?(DEFINE)
       (?<SAFE_CHAR> [a-zA-Z0-9!"\$&'()*+\-.;<=>@[\]^_`{|}~] )
    )
/x
...