2017-02-07 2 views
3

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

my $regex = qr/(daisy|john|fred|june)/is; 

my $test = 'Later John said blah and JOHN said ignore john .....'; 

while($test =~ /($regex)/g) { 
    warn $1; 
} 

# Shows all 3 matches 

Я хотел бы регулярное выражение, чтобы соответствовать каждому вхождение в «Джона» ИЛИ «JOHN» и т. Д., Но НЕ, если первая буква является строчной буквой, например «john» не должна совпадать.

Я мог бы повторить слова регулярных выражений при строительстве, как

/(Daisy|DAISY|John|JOHN|Fred|FRED....)/ 

Но есть какой-то интересный способ не нуждаясь, чтобы сделать это, и регулярное выражение только выдастся если первая буква заглавная?

Я мог бы выполнить 2-й чек вне регулярного выражения после нечувствительного к регистру совпадения в качестве возможного решения и просто игнорировать его, если совпадение! ~/[AZ]/или что-то в этом роде, но мне интересно узнать, есть ли способ внутри одного регулярного выражения добавить дополнительное условие?

+2

Несмотря на то, что обычно, я бы просто придерживаться написания кода в 'perl' и не пытаться писать его в' regex'. Последнее достаточно мощное, но на самом деле это не так хорошо для читаемости. – Sobrique

+3

честно, и я парень-регек, я думаю, что ваше последнее предлагаемое решение - лучший способ. (2-я проверка внешнего регулярного выражения) – sweaver2112

+0

Если это самый интуитивный, я, скорее всего, пойду за это, я просто не был уверен, был ли какой-то «простой» метод, о котором я не знал. – Ian

ответ

2

Добавить взгляд вперед для первой буквы будучи заглавными буквами:

my $regex = qr/(?=[A-Z])(?i)(daisy|john|fred|june)/s 

Используйте случай нечувствительным флаг только после того, как внешний вид вперед.

+1

Обратите внимание, что это решение оставляет вас с ненужной группой # 2. Кроме того, модификатор 's' является избыточным, поскольку нет точки для переопределения поведения в шаблоне. –

+0

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

+0

@ WiktorStribiżew Существует только 1 группа, а не 2. Хотя группа не нужна, я внес минимальное изменение в исходное регулярное выражение, чтобы подчеркнуть, что нужно добавить, чтобы заставить его работать. – Bohemian

3

Вы можете использовать регистрозависимости чера группу (с (?i:...|...)) и требуете первой буквы быть прописной один с (?=\p{Lu}) опережающего просмотром, где \p{Lu} соответствует заглавной букве (таким образом, требуя, чтобы персонаж сразу справа должен быть прописные буквы, не потребляя ее):

#!/usr/bin/perl 
use strict; 
use warnings; 
use feature 'say'; 

my $regex = qr/(?=\p{Lu})(?i:daisy|john|fred|june)/; 

my $test = 'Later John said blah and JOHN said ignore john .....'; 

while($test =~ /($regex)/g) { 
    say $1; 
} 

Смотрите online demo

+0

Что представляет собой \ p {Lu}? –

+0

См. Мои объяснения в верхней части ответа. –

+0

Извините за чтение слишком быстро. Не могли бы вы рассказать мне, где это задокументировано? Я хотел бы знать, является ли UTF-8 дружественным и какие существуют другие варианты этого типа. –

 Смежные вопросы

  • Нет связанных вопросов^_^