Regex 与perl兼容的正则表达式能否比较两个数字?
定位本杰明按钮 鉴于Regex 与perl兼容的正则表达式能否比较两个数字?,regex,pcre,Regex,Pcre,定位本杰明按钮 鉴于 Born,Died 1852,1891 1862,1862 1902,1785 ..,在perl兼容的正则表达式中是否有与第四行匹配的语法,其中第一个值大于第二个值 我猜是某种结合 (\d+),(\d+) 。。。而且 (??{$1>$2}) ..,但这可能是不可能的,因为正则表达式是词法的,匹配是算术的 编辑:由于环境接受pcre模式,但禁止使用perl程序,因此这被限制为pcre正则表达式。Summary 此正则表达式假定源代码是4位字符串。它将查找第一个逗号
Born,Died
1852,1891
1862,1862
1902,1785
..,在perl兼容的正则表达式中是否有与第四行匹配的语法,其中第一个值大于第二个值
我猜是某种结合
(\d+),(\d+)
。。。而且
(??{$1>$2})
..,但这可能是不可能的,因为正则表达式是词法的,匹配是算术的
编辑:由于环境接受pcre模式,但禁止使用perl程序,因此这被限制为pcre正则表达式。Summary
此正则表达式假定源代码是4位字符串。它将查找第一个逗号分隔的数字大于第二个数字的实例。如本文所述,此正则表达式假定您使用的是忽略空白或换行符的“x”标志 正则表达式 样本采集 简短解释 正则表达式的开头有一个前瞻性,以验证我们确实有两个4位数字 四个代码块测试每个位置,以验证一个数字是否大于另一个数字。第二、第三和第四个块包含命名的反向引用(分别为a、b和c)。此反向参考确保前导数字相同 更详细的解释
使用Perl“延迟执行断言”(?{code}))的工作模式是:
^(\d{4}),(\d{4})(??{ $1 > $2 ? "" : "(?!)"})$
延迟执行断言将代码返回的值放入正则表达式中。这种情况下的效果是,如果第一个数字大于第二个数字(因此它匹配),则模式变为^(\d{4}),(\d{4})$
,否则变为^(\d{4}),(\d{4})(?!)$
(?!)
是一个否定的前瞻断言,它从不匹配,因为Perl认为空模式总是匹配的
Perl中的另一个选项是使用“条件表达式”(?(条件)yes模式)
,以及“代码求值断言”(?{code})
:
这将尝试查找具有相同前缀的数字对,并且第二个数字中的第一个不同字符不是非数字(即,它是一个数字),并且不等于或大于第一个数字中的相应数字(即,它小于另一个数字)。不幸的是,它不起作用。原因已在中解释。基本上,反向引用在角色类中不起作用。这个想法可以通过使用延迟执行断言(^(\d*)(\d)\d*,\1(?{{2}-9]})\d*$
)来实现,但这对PCRE仍然没有好处
一个与PCRE兼容的选项是使用强力版本的检查第一个不同的数字。查找1后跟0,或2后跟0或1,或3后跟0或1或2。这段Bash代码生成正则表达式:
regex='^(?=\d{4},\d{4}$)' # Match only lines of the form 'dddd,dddd'
regex+='(\d*)' # Prefix of both numbers
regex+='(1\d*,\1[0]' # 1 (followed by digits+','+prefix) followed by 0
for (( i=2 ; i<=9 ; i++ )) ; do
regex+="|$i\d*,\1[0-$((i-1))]" # or $i (...) followed by a lesser digit
done
regex+=')\d*$'
printf '%s\n' "$regex"
正如@ThisSuiteisBlack在评论中所指出的,正则表达式并不是最好的方法。另请参见。为了澄清,您是要Perl正则表达式还是PCRE正则表达式。另外,在Perl中,如果没有正则表达式(并且更易于阅读),这是一件微不足道的事情:
while(){chomp;my($born,$died)=split/,/;print if$died<$born;}
是否有什么理由必须使用正则表达式?@thisSuitesBlacknot,我个人对{code}的语法很好奇,但手头的问题需要PCRE。根据你提供的链接,手头的问题是没有希望的;除非pcre调出功能可能是一个桥梁。现在,这是一个答案,但很酷的regex魔术:perl-le'$x=“123456”;打印$x=~/(\d),([\1-9])/;打印$1;打印$2;'代码>-只要你处理的是1位数的数字,正则表达式就可以完成你的工作。那怎么办?
[0][0] = 1902,1785
[0][a] = 1
[0][b] =
[0][c] =
[1][0] = 1111,1110
[1][a] =
[1][b] =
[1][c] = 111
[2][0] = 2222,2202
[2][a] =
[2][b] = 22
[2][c] =
[3][0] = 3333,3033
[3][a] = 3
[3][b] =
[3][c] =
[4][0] = 4444,0444
[4][a] =
[4][b] =
[4][c] =
[5][0] = 4567,1234
[5][a] =
[5][b] =
[5][c] =
NODE EXPLANATION
----------------------------------------------------------------------
^ the beginning of a "line"
----------------------------------------------------------------------
(?= look ahead to see if there is:
----------------------------------------------------------------------
\d{4} digits (0-9) (4 times)
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
\d{4} digits (0-9) (4 times)
----------------------------------------------------------------------
(?: group, but do not capture:
----------------------------------------------------------------------
\D non-digits (all but 0-9)
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
\Z before an optional \n, and the end of
the string
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
) end of look-ahead
----------------------------------------------------------------------
(?: group, but do not capture:
----------------------------------------------------------------------
(?: group, but do not capture:
----------------------------------------------------------------------
[9] any character of: '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[012345678] any character of: '0', '1', '2', '3',
'4', '5', '6', '7', '8'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[89] any character of: '8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[01234567] any character of: '0', '1', '2', '3',
'4', '5', '6', '7'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[789] any character of: '7', '8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[0123456] any character of: '0', '1', '2', '3',
'4', '5', '6'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[6789] any character of: '6', '7', '8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[012345] any character of: '0', '1', '2', '3',
'4', '5'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[56789] any character of: '5', '6', '7', '8',
'9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[01234] any character of: '0', '1', '2', '3',
'4'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[456789] any character of: '4', '5', '6', '7',
'8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[0123] any character of: '0', '1', '2', '3'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[3456789] any character of: '3', '4', '5', '6',
'7', '8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[012] any character of: '0', '1', '2'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[23456789] any character of: '2', '3', '4', '5',
'6', '7', '8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[01] any character of: '0', '1'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
[123456789] any character of: '1', '2', '3', '4',
'5', '6', '7', '8', '9'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
, ','
----------------------------------------------------------------------
[0] any character of: '0'
----------------------------------------------------------------------
\d* digits (0-9) (0 or more times
(matching the most amount possible))
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
| OR
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
) end of grouping
^(\d{4}),(\d{4})(??{ $1 > $2 ? "" : "(?!)"})$
^(\d{4}),(\d{4})(?(?{ $1 <= $2 })(?!))$
^(\d*)(\d)\d*,\1[^\D\2-9]\d*$
regex='^(?=\d{4},\d{4}$)' # Match only lines of the form 'dddd,dddd'
regex+='(\d*)' # Prefix of both numbers
regex+='(1\d*,\1[0]' # 1 (followed by digits+','+prefix) followed by 0
for (( i=2 ; i<=9 ; i++ )) ; do
regex+="|$i\d*,\1[0-$((i-1))]" # or $i (...) followed by a lesser digit
done
regex+=')\d*$'
printf '%s\n' "$regex"
^(?=\d{4},\d{4}$)(\d*)(1\d*,\1[0]|2\d*,\1[0-1]|3\d*,\1[0-2]|4\d*,\1[0-3]|5\d*,\1[0-4]|6\d*,\1[0-5]|7\d*,\1[0-6]|8\d*,\1[0-7]|9\d*,\1[0-8])\d*$