2015-02-12 2 views
0

У меня есть файл с представлением, как этотИспользование Perl, чтобы проверить, если строка имеет только английские символы

%TRYYVJT128F93506D3<SEP>SOYKCDV12AB0185D99<SEP>Rainie Yang<SEP>Ai Wo Qing shut up (OT: Shotgun(Aka Shot Gun)) 
%TRYYVHU128F933CCB3<SEP>SOCCHZY12AB0185CE6<SEP>Tepr<SEP>Achète-moi 

Я вскрышное все, кроме названия песни, используя это регулярное выражение.

$line =~ s/.*>|([([\/\_\-:"``+=*].*)|(feat.*)|[?¿!¡\.;&\[email protected]%#\\|]//g; 

Я хочу, чтобы убедиться, что только строки, напечатанные являются те, которые содержат только латинские символы, поэтому в данном случае это было бы первое название Ai Wo Quing shut up песни, а не следующий из-за è.

Я попробовал этот

if ($line =~ m/[^a-zA-z0-9_]*$/) { 
    print $line; 
} 
else { 
    print "Non-english\n"; 

я думал, что это будет соответствовать только английские символы, но он всегда печатает Non-english. Я чувствую, что это я ржавый с регулярным выражением, но я не могу найти ответ.

+0

Обратите внимание на свой класс символов: 'a-zA-z'.Они чувствительны к регистру, а 'A-z' покрывает LOT больше символов, чем' A-Z'. –

+5

Ваше регулярное выражение - у вас есть '^' в неправильном месте. Он должен находиться за пределами скобок. – Sobrique

+0

Приносим извинения, что это [a-zA-Z0-9_ ']. Перемещение^на внешнюю сторону скобок зафиксировало это. Спасибо Sobrique! – thechucklingatom

ответ

2

Исходя из комментариев, ваша проблема, казалось бы:

конкретно - ^ находится внутри скобок, что означает, что он не выступает в качестве «якоря». Это на самом деле является отрицанием оператор

См: http://perldoc.perl.org/perlrecharclass.html#Negation

Также можно вместо этого перечислить символы, которые вы не хотите, чтобы соответствовать. Вы можете сделать это, используя каретку (^) в качестве первого символа в классе символов. Например, [^ a-z] соответствует любому символу, который не является строчной буквой ASCII, поэтому он содержит более миллиона кодовых точек Unicode. Класс называется «отрицательным» или «перевернутым».

Но важная часть - это то, что без якоря «начала строки» ваше регулярное выражение равно нулю или больше экземпляров (чего бы то ни было), поэтому будет соответствовать практически всему - потому что он может свободно игнорировать лайн.

(Ответ Бородина охватывает некоторые другие варианты для такого типа совпадений, поэтому я не буду воспроизводить).

1

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

Это, вероятно, лучше всего, если вы используете split разделить каждую строку данных на <SEP>, который я предполагаю, это сепаратор. Ваш вопрос просит четвертое такое поле, как этот

use strict; 
use warnings; 
use 5.010; 

while (<DATA>) { 
    chomp; 
    my @fields = split /<SEP>/; 
    say $fields[3]; 
} 

__DATA__ 
%TRYYVJT128F93506D3<SEP>SOYKCDV12AB0185D99<SEP>Rainie Yang<SEP>Ai Wo Qing shut up (OT: Shotgun(Aka Shot Gun)) 
%TRYYVHU128F933CCB3<SEP>SOCCHZY12AB0185CE6<SEP>Tepr<SEP>Achète-moi 

выход

Ai Wo Qing shut up (OT: Shotgun(Aka Shot Gun)) 
Achète-moi 

Кроме того, класс word персонажа \w матчей точно [a-zA-z0-9_]\W матчей дополнения), поэтому вы можете переписать if заявление, подобное этому

if ($line =~ /\W/) { 
    print "Non-English\n"; 
} 
else { 
    print $line; 
} 
Смежные вопросы