Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 [ 13 ] 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

базами данных поддерживают списки полей, разделенных запятыми, в качестве стандартного формата для обмена данными.

Решение

Воспользуйтесь следующей процедурой:

sub parse csv {

my $text = shift; # Запись со значениями, разделенными запятыми

ту (Snew = ();

push((anew, $+) while $text =" m{

# Первая часть группирует фразу в кавычках (["\Л\]*(.\\.["\Л\]0*)-, I (",]+), I ,

}дх;

push(@new, undef) if substr($text,-1,1) eq ,;

return @new, # Список значений, которые разделялись запятыми

Также можно воспользоваться стандартным модулем Text:ParseWords:

use Text:.ParseWords,

sub parse csv {

return quoteword(, , 0, $ [0],

Комментарий

Ввод данных, разделенных запятыми, - коварная и непростая задача. Все выглядит просто, но в действительности приходится использовать довольно сложную систему служебных символов, поскольку сами поля могут содержать внутренние запятые. В результате подстановка получается весьма сложной, а простая функция split /, / вообще исключается.

К счастью, модуль Text::ParseWords скрывает от вас все сложности. Передайте функции qoutewords два аргумента и строку разделенных данных. Первый аргумент определяет символ-разделитель (в данном случае - запятая), а второй - логический флаг, который показывает, должна ли возвращаемая строка содержать внутренние кавычки.

Если кавычки должны присутствовать внутри поля, также ограниченного кавычками, воспользуйтесь префиксом \: "like \"this\". Кавычки, апострофы и обратная косая черта - единственные символы, для которых этот префикс имеет специальное значение. Все остальные экземпляры \ остаются в итоговой строке.

Ниже показан пример использования процедуры parse csv. q<> - всего лишь хитроумный заменитель кавычек, благодаря которому нам не придется расставлять повсюду символы \.

$line = q<XYZZY, "",ОReilly, Inc,"Wall, Larry","а \"glug\" bit,",5,



1.16. Сравнение слов с похожим звучанием 57

"Error, Core Dumped">, (Sfields = parse csv($line), for ($1 = 0,$i < @fields; $i++) {

print "$i . $fields[$i]\n";

0 : XYZZY

2 : OReilly, Inc

3 : Wall, Larry

4 : a \"glug\" bit,

5 : 5

6 ; Error, Core Dumped

> Смотри также-

Описание синтаксиса регулярных выражений в perlre(l); документация по стандартному модулю Text::ParseWords.

1.16. Сравнение слов с похожим звучанием

Проблема

Имеются две английские фамилии. Требуется узнать, звучат ли они похожим образом (независимо от написания). Это позволит выполнять неформальный поиск в телефонной книге, в результатах которого наряду со Smith будут присутствовать и другие похожие имена - например, Smythe, Smite и Smote.

Решение

Воспользуйтесь стандартным модулем Text::Soundex:

use Text .Soundex;

SCODE = soundex($STRING); (SCODES = soundex((aLIST);

Комментарий

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

Следующая программа предлагает ввести имя и ищет в файле паролей имена с похожим звучанием. Аналогичный подход может использоваться для баз данных имен, поэтому при желании можно индексировать базу данных по ключам soundex. Конечно, такой индекс не будет уникальным.



1.17. Программа: fixstyle

Представьте себе таблицу с парами устаревших и новых слов.

Старые слова

Новые слова

bonnet

hood

rubber

eraser

lorrie

truck

trousers

pants

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

При вызове без файловых аргументов программа выполняет функции простого фильтра. Если в командной строке передаются имена файлов, то в них помещаются результаты, а прежние версии сохраняются в файлах с расширениями *.orig (см. рецепт 7.9). При наличии параметра командной строки -v сообщения обо всех изменениях записываются в STDERR.

Таблица пар «исходное слово/заменитель» хранится в основной программе, начиная с END (см. рецепт 7.6). Каждая пара преобразуется в подстановку и накапливается в переменной $code так же, как это делается в программе popgrep2 из рецепта 6.10.

use Text::Soundex; use User::pweht;

print "Lookup user: "; chomp($user = <STDIN>); exit unless defined $user; $name code = soundex($user);

while($uent = getpwentO) {

(Sfirstname, Slastname) = $uent->gecos =~ /(w+)[", ]Ab(\w+)/;

if ($name code eq soundex($uent->naffle) $name code eq soundex($$lastname) $naffle code eq soundex($firstname) )

printf "%s: %s %s\n", $uent->naffle, $firstname, $lastname;

> Смотри также-

Документация по стандартным модулям Text:;Soundex и User:;pwent; man-страница passwd(5) вашей системы; «Искусство программирования», том 3, глава 6.



0 1 2 3 4 5 6 7 8 9 10 11 12 [ 13 ] 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242