【问题标题】:Match words in regex, but only if first letter is upper case匹配正则表达式中的单词,但前提是首字母为大写
【发布时间】:2017-02-07 14:20:33
【问题描述】:

我有一个动态构建的较大的正则表达式,例如缩短的文本示例

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”等,但如果第一个字母是小写字母则不匹配,例如“john”不应该匹配。

我可以在构建时重复正则表达式,比如

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

但是有没有一些有趣的方法不需要这样做,并且正则表达式仅在第一个字母是大写字母时才匹配?

我可以在不区分大小写的匹配之后在正则表达式之外运行第二次检查作为可能的解决方案,如果匹配则忽略它!~ /[A-Z]/ 或其他东西,但我很想知道是否有在同一个正则表达式中添加额外条件的方式?

【问题讨论】:

  • 虽然通常有,但我会坚持在perl 中编写您的代码,而不是尝试在regex 中编写它。后者相当强大,但它的可读性确实不是那么好。
  • 老实说,我是一个正则表达式的人,我认为你最后提出的解决方案是最好的方法。 (第二次检查外部正则表达式)
  • 如果它是最直观的,我可能会去谢谢,我只是不确定是否有一些我不知道的“简单”方法。

标签: regex perl


【解决方案1】:

您可以使用不区分大小写的交替组(使用(?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

【讨论】:

  • \p{Lu} 代表什么?
  • 在答案顶部查看我的解释。
  • 抱歉读得太快了。你能告诉我这是在哪里记录的吗?我想知道它是否对 UTF-8 友好,以及这种类型的其他选项是否存在。
  • 你可以在Properties accessible through \p{} and \P{}阅读更多关于它们的信息。
  • 谢谢!不错的资源。
【解决方案2】:

为第一个大写字母添加前瞻:

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

仅在向前看之后使用不区分大小写的标志。

【讨论】:

  • 请注意,此解决方案会给您留下不必要的组 #2。此外,s 修饰符是多余的,因为没有点可以重新定义模式中的行为。
  • 感谢 Wiktor 的帮助,我认为这个答案对于以后阅读我的代码的其他人来说更直观,即使它有副作用,但我觉得我从你的答案中学到了更多。
  • @WiktorStribiżew 只有 1 个组,而不是 2 个。虽然组是不必要的,但我对原始正则表达式进行了最小的更改,以强调需要添加的内容才能使其正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多