Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 仅当存在';字符串中的一个小写字母,带有一个正则表达式_Regex_Perl_Pcre - Fatal编程技术网

Regex 仅当存在';字符串中的一个小写字母,带有一个正则表达式

Regex 仅当存在';字符串中的一个小写字母,带有一个正则表达式,regex,perl,pcre,Regex,Perl,Pcre,我偶然发现了这个看似微不足道的问题,我被困在上面了。我有一个字符串,我想在一个正则表达式中匹配,所有大写单词,只要字符串中至少有一个小写字母 基本上,我想要每一行(我们可以考虑将ReEX单独应用到每一行,不需要多行处理)输出: ab ABC//匹配或捕获ABC ab ABC 12 CD//匹配或捕获ABC,CD ABC DE//不匹配或不捕获任何内容(无小写) ABC 23 DE EFG a//匹配或捕获ABC、DE、EFG AB aF DE//匹配或捕获AB,DE 我使用PCRE作为正则表达

我偶然发现了这个看似微不足道的问题,我被困在上面了。我有一个字符串,我想在一个正则表达式中匹配所有大写单词,只要字符串中至少有一个小写字母

基本上,我想要每一行(我们可以考虑将ReEX单独应用到每一行,不需要多行处理)输出:

ab ABC//匹配或捕获ABC
ab ABC 12 CD//匹配或捕获ABC,CD
ABC DE//不匹配或不捕获任何内容(无小写)
ABC 23 DE EFG a//匹配或捕获ABC、DE、EFG
AB aF DE//匹配或捕获AB,DE
我使用PCRE作为正则表达式风格(我知道其他一些风格允许可变长度的后视)

评论后更新

显然,如果我使用多个正则表达式或我正在使用的程序语言调用正则表达式,有很多简单的解决方案(例如,首先通过查找小写字母验证字符串,然后将所有大写单词与两个不同的正则表达式匹配)

我的目标是找到一种使用一个正则表达式的方法

对于这一限制,我没有技术上的必要性。如果有必要,可以把它当作一种风格练习,或者好奇,或者我尝试提高我的正则表达式技能:这项任务(一开始)看起来很简单,我想知道是否只有一个正则表达式就可以完成。如果不能,我想知道原因

或者,如果可以,但regex不是为这类任务设计的,我希望知道为什么——或者至少知道什么是“这类不适合的任务”,这样我就可以在遇到它们时选择正确的解决方案



那么,它在一个正则表达式中可行吗 因此
\G
最初设置为位置0处的匹配条件。
这意味着在多线模式下,BOS必须是一种特殊情况。
即使BOString是一个BOLine,如果断言
(?=^.*[a-z])
失败,
\G
最初设置为匹配(默认值?),未经验证即可找到UC单词

(?|(?=\A.*[a-z]).*?\b([A-Z]+)\b|(?!\A)(?:(?=^.*[a-z])|\G.*?\b([A-Z]+)\b))
更新2为后代发布。
与@Robin讨论后,可以将上述正则表达式重构为:

 #  (?:(?=^.*[a-z])|(?!\A)\G).*?\b([A-Z]+)\b

 (?:
      (?= ^ .* [a-z] )        # BOL, check if line has lower case letter
   |                        # or
      (?! \A )                # Not at BOS (beginning of string, where \G is in a matched state)
      \G                      # Start the match at the end of last match (if previous matched state)
 )
 .*? \b 
 ( [A-Z]+ )              # (1), Found UC word
 \b     
Perl测试用例:

$/ = undef;

$str = <DATA>;

@ary = $str =~ /(?:(?=^.*[a-z])|(?!\A)\G).*?\b([A-Z]+)\b/mg;

print "@ary", "\n-------------\n";

while ($str =~ /(?:(?=^.*[a-z])|(?!\A)\G).*?\b([A-Z]+)\b/mg)
{
   print "$1 ";
}

__DATA__
DA EFR
ab ABC
ab ABC 12 CD
ABC DE  t
ABC 23 DE EFG a

愚蠢的问题值得愚蠢的回答

/(?{ @matches = m{\b\p{Lu}+\b}g if m{\p{Ll}} })/;
测试:

浓缩成

my @matches = /\G(?:(?!^)|(?=.*\p{Ll})).*?(\b\p{Lu}+\b)/sg;

在字符串的开头,它向前看一个小写字母。在其他任何地方,都不需要检查,因为我们已经检查过了。

也许我们考虑过了:

#! /usr/bin/env perl
#
use strict;
use feature qw(say);
use autodie;
use warnings;
use Data::Dumper;

while ( my $string = <DATA> ) {
    chomp $string;
    my @array;
    say qq(String: "$string");
    if ( @array = $string =~ /(\b[A-Z]+\b)/g ) {
        say qq(String groups: ) . join( ", ", @array ) . "\n";
    }
}

__DATA__
ab ABC
ab ABC 12 CD
ABC DE
ABC 23 DE EFG a
AB aF DE
ADSD asd ADSD
asd ADSDSD
SDSD SDD SD
SSDD SDS asds

我错过了什么吗?

我不确定这是否可以做到,但这里有一些背景信息,稍微解释一下“为什么”部分

正则表达式是为匹配而设计的,最初,它们只能做到这一点。事实上,正则语法是最简单的语法之一,但并不完全是琐碎的;例如,大多数现代计算机语言使用非规则语法。(特别是见)

因此,正则表达式所能描述的语言是有限度的,而你能用一些简单的英语句子来描述的语言则要有限得多

这是一种将语言划分为不同表达水平的方法。请注意,常规语法始终位于底部,最有用的(编程)语言要么是类型3,要么是边界类型3(即添加了一些类型3部分)。这是由于一个简单的事实:我们的大脑相当有能力处理上下文敏感(类型3)语法,甚至是复杂的语法(因此我们希望编程语言功能强大)。然而,上下文相关语法的计算机解析器要比Type-2的计算机解析器慢很多(因此,我们希望编程语言的能力受到限制

对于预期匹配速度非常快的正则表达式,限制其整体表达能力更为重要。但是,通过编写两个或多个添加了一些控制结构的正则表达式,可以有效地扩展它们,使其比正则表达式解析器更强大。

一个正则表达式:

@words = split (/[a-z]+/, $_);

为什么不用你正在使用的语言做一些简单的事情呢。PHP:
if(preg_match('/[a-z]/',$string){$string=strtoupper($string);}
我知道这是一个很长的问题,但请阅读免责声明部分:许多简单实用的解决方案如果我们不局限于纯正则表达式,我想知道这在一个正则表达式中是否可行。我不这么认为。正则表达式本质上返回“匹配”或“不匹配”我们有两种匹配状态:整个expr是否匹配小写字母以及大写字母在哪里。你需要单独的正则表达式来执行这些单独的匹配。糟糕!我只是快速浏览了一下:)感谢您的帮助!但是,如果字符串仅为
A BC
:它不应该选择任何内容,而是选择了。因为我对
\G
不是很满意(而且还不完全理解为什么您的正则表达式在其他情况下似乎可以工作)我不知道这是否是一个很难解决的问题。顺便说一句,我想现在的答案不需要是多行的,我们可以分别使用每一行。而且我也不确定你是否真的需要最后一个非捕获括号。是的,我想它是成立的!感谢多行解决方案。很少有评论:1.严格来说,我相信正则表达式可以被重构为
(?:(?=\A.[A-z])|(?!\A)(?:(?=^.[A-z])|(?!^)\G))。\b([A-z]+)\b
.2.关于
\G
的默认匹配,如果您认为可以这样做:
(?:(?=^.[A-z])|(?!^)\G.*?\b([A-z]+)\b
,因为BOS是一个BOL。您是否同意添加
,取出它可以重构为
(?:(?=\A.[A-z])|(?!\A)(?:(?=^..[A-z])|\G))。\b([A-z]+)\b
。回答2这
(?=^.[A-z])|(?!^)\G
的唯一原因是将
\G
的初始正则表达式启动匹配状态翻转为
不匹配。仅此而已。完成后,这项工作将正常进行,因为
\G
自然会进入unm
my @matches = /\G(?:(?!^)|(?=.*\p{Ll})).*?(\b\p{Lu}+\b)/sg;
#! /usr/bin/env perl
#
use strict;
use feature qw(say);
use autodie;
use warnings;
use Data::Dumper;

while ( my $string = <DATA> ) {
    chomp $string;
    my @array;
    say qq(String: "$string");
    if ( @array = $string =~ /(\b[A-Z]+\b)/g ) {
        say qq(String groups: ) . join( ", ", @array ) . "\n";
    }
}

__DATA__
ab ABC
ab ABC 12 CD
ABC DE
ABC 23 DE EFG a
AB aF DE
ADSD asd ADSD
asd ADSDSD
SDSD SDD SD
SSDD SDS asds
String: "ab ABC"
String groups: ABC

String: "ab ABC 12 CD"
String groups: ABC, CD

String: "ABC DE"
String groups: ABC, DE

String: "ABC 23 DE EFG a"
String groups: ABC, DE, EFG

String: "AB aF DE"
String groups: AB, DE

String: "ADSD asd ADSD"
String groups: ADSD, ADSD

String: "asd ADSDSD"
String groups: ADSDSD

String: "SDSD SDD SD"
String groups: SDSD, SDD, SD

String: "SSDD SDS asds"
String is groups: SSDD, SDS
@words = split (/[a-z]+/, $_);