Perl строки манипуляции и найти - PullRequest
0 голосов
/ 18 октября 2018

В настоящее время я работаю над программой телефонной книги для класса, и у меня возникли небольшие проблемы с частью регулярного выражения, чтобы отформатировать текст и найти то, что я ищу.Во-первых, у меня проблемы с редактированием текста моего номера телефона в соответствии с тем, что я хочу.Я могу найти текст с 7 числами в строке (777777), но не могу заменить его на (1-701-777-777).

if($splitIndex[1] =~ m/^(\d{3}\d{4})/) {
      $splitIndex[1] =~ s/([\d{3}][\d{4}])/1-701-[$1]-[$2]/;
      print "Updated: $splitIndex[1]";
    }

Когда я запускаю этот код,в результате получается (не позвольте мне вставить изображение здесь выводится https://imgur.com/a/8HtW7xm).

Во-вторых, у меня возникают проблемы с выполнением фактической части регулярного выражения для поиска. Я сохраняю все возможные комбинации букв в $ letofSearch и числоКомбинация порядка в $ numOfSearch. Играя в регулярных выражениях, я понял, что если я сделаю [$ numOfSearch] + [$ numOfSearch [-1] ... [$ numOfSearch [1], это даст мне правильный поиск чисел, но яя не могу написать это правильно в моем коде.

    #If user input is only numbers
    if($searchValue =~ m/(\D)/) {
      #print "Not a number\n";
      if($splitIndex[1] =~ m/([$numOfSearch]+)/) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      if($splitIndex[0] =~ m/([$letOfSearch])/i) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      $found = 0;
    } else {
      #If it is a number search for that number combo immedietly
      if($splitIndex[1] =~ m/([$numOfSearch]+)/) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      if($splitIndex[0] =~ m/([$letOfSearch])/i) {
        if($found == 0) {
            print "$splitIndex[0]:$splitIndex[1]\n";
            $found = 1;
        }
      }
      $found = 0;
    }
  }
}

1 Ответ

0 голосов
/ 18 октября 2018

Вместо:

if($splitIndex[1] =~ m/^(\d{3}\d{4})/) {
      $splitIndex[1] =~ s/([\d{3}][\d{4}])/1-701-[$1]-[$2]/;
      print "Updated: $splitIndex[1]";
    }

попробуйте это:

if ($splitIndex[1] =~ s/(\d{3})(\d{4})/1-701-$1-$2/)
{
    print "Updated: $splitIndex[1]";
}

В регулярных выражениях набор квадратных скобок ([ и ]) будет соответствовать один и только один символ, независимо от того, что находится в скобках.Поэтому, когда вы пишете [\d{3}][\d{4}], это будет соответствовать ровно двум символам , потому что вы используете два набора [].И эти два символа будут одним из \d (любая цифра), {, 3, 4 или }, потому что это то, что вы написали в скобках.

Порядокне имеет значения внутри квадратных скобок регулярного выражения, поэтому [\d{3}] совпадает с [}1527349806{3].Как видите, это, вероятно, не то, что вы хотели.

То, что вы хотели сделать, это захват строк \d{3} и \d{4}, и вы делаете это с обычным набором захват скобок, например: (\d{3})(\d{4})

Поскольку у вас был только один набор скобок (то есть, у вас было ([\d{3}][\d{4}])), и он содержал ровно две [] с,складывал ровно два символа в 1 доллар, а вообще ничего в 2 доллара.Вот почему, когда вы пытались использовать $ 2 во второй половине вашего s///, он жаловался на неинициализированное значение в $ 2.Вы пытались использовать значение ($ 2), которое просто не было задано.

(Кроме того, вы делали два набора совпадений: один для m// и один для s///. Iпросто удалил совпадение m// и сохранил совпадение s///, используя его возвращаемое значение, чтобы определить, нужно ли что-либо печатать ().)

Вторая часть s/// не использует регулярные выраженияТаким образом, любой [, ], {, }, ( или ) будет буквально отображаться как этот символ.Поэтому, если вы не хотите использовать квадратные скобки в конечном номере телефона, не используйте их.Вот почему я использовал s/.../1-701-$1-$2/; вместо s/.../1-701-[$1]-[$2]/;.

Так что, когда вы писали s/([\d{3}][\d{4}])/1-701-[$1]-[$2]/, часть ([\d{3}][\d{4}]) помещала два символа в $ 1, а ничто в $ 2.Вот почему вы получили результат, который содержал [77] (который был $ 1, заключенный в скобки) и [] (который был $ 2 (неинициализированное значение), заключенное в скобки).

Что касается второй части вашегопост, я заметил, что вы используете много скобок в своих регулярных выражениях, но вы никогда не используете то, что вы захватываете.То есть вы никогда не используете $ 1 (или $ 2).Например, вы пишете:

if($searchValue =~ m/(\D)/) {

с m/(\D)/, но вы никогда не используете $ 1 где-либо в этом коде.Интересно: какой смысл захватывать этот нецифровый символ, если вы нигде не используете его в своем коде?

Я видел, как программисты запутались и перепутали назначение скобок и квадратных скобок.При использовании регулярных выражений квадратные скобки ([ и ]) соответствуют (без захвата) ровно одному символу.Они соответствуют , а не в $ 1, $ 2 или любым другим круглым скобкам $ n.

, с другой стороны, захватывают независимо от того, что они совпадают, устанавливая $ 1(или $ 2, $ 3 и т. д.) к тому, что было сопоставлено.В общем, вам не следует использовать скобки, если вы не планируете захватить и использовать это совпадение позже.(Основное исключение из этого правила - если вам нужно сгруппировать набор совпадений, например: m/I have a (cat|dog|bird)/.)

Многие программисты путают квадратные скобки и скобки в регулярных выражениях и пытаются использовать их взаимозаменяемо.Они напишут что-то вроде m/I have a [cat|dog|bird]/ и не поймут, что это то же самое, что и m/I have a [abcdgiort|]/ (который ничего не захватывает, поскольку нет скобок), и удивятся, почему их программа жалуется, что $ 1 является неинициализированным значением.

Это распространенная ошибка, поэтому не расстраивайтесь, если вы не знали разницу.Теперь вы знаете, и, надеюсь, вы сможете выяснить, что нужно исправить во второй части вашего кода.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...