我在RosettaCode上找到了以下Java代码示例:
public static boolean prime(int n) {
return !new String(new char[n]).matches(".?|(..+?)\\1+");
}
Run Code Online (Sandbox Code Playgroud)
如何.?|(..+?)\\1+匹配素数?
我正在尝试使用正则表达式将字符串分成两部分.字符串格式如下:
text to extract<number>
Run Code Online (Sandbox Code Playgroud)
我一直在使用(.*?)<,<(.*?)>哪个工作正常,但在阅读了一点regex之后,我才开始想知道为什么我需要?表达式中的.我通过这个网站找到它们之后才这样做,所以我不确定它们之间的区别.
这是一系列教育正则表达式文章的第二部分.它显示了向前看符号和嵌套引用如何可以用来匹配非正规languge ñ b ñ.嵌套引用首先介绍在:这个正则表达式如何找到三角形数字?
其中一种原型非常规语言是:
L = { añbñ: n > 0 }
这是所有非空字符串的语言,由一些数字a后跟相同数量的字符串组成b.在这个语言字符串的例子有ab,aabb,aaabbb.
这种语言可以通过泵浦引理显示为非规则的.它实际上是一种原型上下文无关语言,可以通过无上下文语法 生成S ? aSb | ab.
尽管如此,现代正则表达式实现清楚地认识到的不仅仅是常规语言.也就是说,它们不是形式语言理论定义的"规则".PCRE和Perl支持递归正则表达式,.NET支持平衡组定义.更少的"花哨"特征,例如反向引用匹配,意味着正则表达式不规则.
但这个"基本"功能有多强大?L例如,我们可以用Java正则表达式识别吗?我们也许可以结合lookarounds和嵌套引用,并具有与如工作模式String.matches来匹配字符串一样ab,aabb,aaabbb,等?
java.util.regex.Pattern定义:
回文是单词,短语,数字或其他单元序列,具有在任一方向上读取相同的属性
如何检查给定的字符串是否是回文?
这是前一段时间的FAIQ [常见问题访谈问题]之一,但主要是使用C.
寻找任何和所有语言的解决方案.
这是一系列教育正则表达式文章的一部分,这是对嵌套引用概念的温和介绍.
前几个三角形数字是:
1 = 1
3 = 1 + 2
6 = 1 + 2 + 3
10 = 1 + 2 + 3 + 4
15 = 1 + 2 + 3 + 4 + 5
Run Code Online (Sandbox Code Playgroud)
有很多方法可以检查数字是否为三角形.有一种有趣的技术使用正则表达式如下:
^(\1.|^.)+$
以下是一些片段,表明它适用于多种语言:
$r = '/^(\1.|^.)+$/';
foreach (range(0,50) as $n) {
if (preg_match($r, str_repeat('o', $n))) {
print("$n ");
}
}
Run Code Online (Sandbox Code Playgroud)
for (int n = 0; n <= 50; …Run Code Online (Sandbox Code Playgroud) 我一直认为Java的regex-API(以及许多其他语言)中的后视断言必须具有明显的长度.因此,STAR和PLUS量词不允许在内部观察.
优秀的在线资源regular-expressions.info似乎证实了(某些)我的假设:
"[...] Java通过允许有限重复更进一步.你仍然不能使用星号或加号,但你可以使用问号和花括号与指定的max参数.Java认识到有限重复的事实可以重写为具有不同但固定长度的字符串的交替.不幸的是,当你在lookbehind中使用交替时,JDK 1.4和1.5有一些错误.这些在JDK 1.6中被修复.[...]"
只要外观中字符范围的总长度小于或等于Integer.MAX_VALUE,就可以使用大括号.所以这些正则表达式是有效的:
"(?<=a{0," +(Integer.MAX_VALUE) + "})B"
"(?<=Ca{0," +(Integer.MAX_VALUE-1) + "})B"
"(?<=CCa{0," +(Integer.MAX_VALUE-2) + "})B"
Run Code Online (Sandbox Code Playgroud)
但这些不是:
"(?<=Ca{0," +(Integer.MAX_VALUE) +"})B"
"(?<=CCa{0," +(Integer.MAX_VALUE-1) +"})B"
Run Code Online (Sandbox Code Playgroud)
但是,我不明白以下几点:
当我运行使用内部的*和+量词测试向后看,一切顺利的话(见输出测试1和测试2).
但是,当我在的开头添加一个字符向后看,从测试1和测试2,它打破(见输出测试3).
让测试3不情愿的贪婪*没有效果,它仍然会中断(参见测试4).
这是测试工具:
public class Main {
private static String testFind(String regex, String input) {
try {
boolean returned = java.util.regex.Pattern.compile(regex).matcher(input).find();
return "testFind : Valid -> …Run Code Online (Sandbox Code Playgroud) 这个问题是在PCRE模式中使用前瞻,嵌套引用和条件来匹配所有回文的教育演示,包括PCRE手册页中给出的递归模式无法匹配的回文.
在PHP代码段中检查此PCRE模式:
$palindrome = '/(?x)
^
(?:
(.) (?=
.*
(
\1
(?(2) \2 | )
)
$
)
)*
.?
\2?
$
/';
Run Code Online (Sandbox Code Playgroud)
这种模式似乎可以检测到回文,如本测试案例所示(另见ideone.com):
$tests = array(
# palindromes
'',
'a',
'aa',
'aaa',
'aba',
'aaaa',
'abba',
'aaaaa',
'abcba',
'ababa',
# non-palindromes
'aab',
'abab',
'xyz',
);
foreach ($tests as $test) {
echo sprintf("%s '%s'\n", preg_match($palindrome, $test), $test);
}
Run Code Online (Sandbox Code Playgroud)
那么这种模式如何运作?
此模式使用嵌套引用,这是此Java正则表达式如何检测回文中使用的类似技术?,但与Java模式不同,没有外观(但确实使用了条件).
另请注意,PCRE 手册页提供了一个递归模式以匹配一些回文:
# the recursive pattern to detect …Run Code Online (Sandbox Code Playgroud) 我主要关心的是Java风格,但我也很欣赏有关其他人的信息.
假设你有一个像这样的子模式:
(.*)(.*)
Run Code Online (Sandbox Code Playgroud)
虽然不是很有用,但是让我们说这两个捕获组(比如说,\1和\2)是一个更大的模式的一部分,它与这些组的反向引用相匹配,等等.
所以两者都是贪婪的,因为他们尽可能地捕捉,只在必要时减少.
我的问题是:谁更贪婪?是否\1优先考虑,\2仅在必要时给予其份额?
关于什么:
(.*)(.*)(.*)
Run Code Online (Sandbox Code Playgroud)
让我们假设\1确实是第一优先.让我们说它过于贪婪,然后吐出一个角色.谁先得到它?它总是\2或可以\3吗?
让我们假设这\2是被\1拒绝的.如果这仍然不起作用,谁现在吐出来?是\2吐\3,还是先\1吐出另一个\2?
如果你写这样的东西会发生什么:
(.*)(.*?)(.*)
Run Code Online (Sandbox Code Playgroud)
现在\2不情愿.这是否意味着\1吐出来\3,\2只是不情愿地接受了\3拒绝?
也许我没有给出具体的例子来说明我是如何使用这些模式的,这可能是一个错误,但这里有一些:
System.out.println(
"OhMyGod=MyMyMyOhGodOhGodOhGod"
.replaceAll("^(.*)(.*)(.*)=(\\1|\\2|\\3)+$", "<$1><$2><$3>")
); // prints "<Oh><My><God>"
// same pattern, different input string
System.out.println(
"OhMyGod=OhMyGodOhOhOh"
.replaceAll("^(.*)(.*)(.*)=(\\1|\\2|\\3)+$", "<$1><$2><$3>")
); // prints "<Oh><MyGod><>"
// now \2 is reluctant
System.out.println( …Run Code Online (Sandbox Code Playgroud) 这是一系列教育正则表达式文章的第四部分.它展示了嵌套引用的组合(请参阅:这个正则表达式如何找到三角形数??)在断言中"计数"(参见:我们如何匹配^ nb ^ n与Java正则表达式?)可用于反转字符串.以编程方式生成的模式使用元模式抽象(请参阅:此Java正则表达式如何检测回文?).这是系列中的第一次,这些技术用于替换而不是整个字符串匹配.
提供了完整的Java和C#实现.鼓舞人心的报价包括在内.
使用正则表达式反转字符串似乎不是一个好主意,如果它完全可能,它甚至不会立即显而易见,如果是这样,人们可能会尝试这样做.
虽然它仍然不是一个好主意,但至少现在我们知道这是可能的,因为这是一种方法:
using System;
using System.Text.RegularExpressions;
public class TwoDollarReversal {
public static void Main() {
string REVERSE =
@"(?sx) . grab$2"
.Replace("grab$2",
ForEachDotBehind(
AssertSuffix(@"((.) \1?)")
)
);
Console.WriteLine(
Regex.Replace(
@"nietsniE treblA --
hguone llew ti dnatsrednu t'nod uoy ,ylpmis ti nialpxe t'nac uoy fI",
REVERSE, "$2"
)
);
// If you can't explain it simply, you don't understand it well enough
// -- …Run Code Online (Sandbox Code Playgroud) 在阅读了polygenelubricants关于高级正则表达式技术的系列文章后(特别是这个Java正则表达式如何检测回文?),我决定尝试创建自己的PCRE正则表达式来解析回文,使用递归(在PHP中).
我想出的是:
^(([a-z])(?1)\2|[a-z]?)$
Run Code Online (Sandbox Code Playgroud)
我对这个表达式的理解是它应该匹配零个或一个字符(每个小于2个字符的字符串隐含一个回文,以及在递归中考虑奇数长度的回文),或者两个相同的字符分开通过模式的递归.
不幸的是,它似乎没有那样工作,你可以在www.ideone.com/a9T3F上看到.取而代之的是,只有2的弦ñ - 1(.即空字符串,a,aaa,aaaaaaa,一15)重复字符匹配正则表达式.
奇怪的是,如果我改变我的模式,这样的递归是可选的(即^(([a-z])(?1)?\2|[a-z]?)$,见www.ideone.com/D6lJR,它只匹配反复2字符串ñ倍(即空字符串,a,aa,aaaa,aaaaaaaa,一16) .
为什么我的正则表达式没有像我期望的那样工作?
注意那些渴望建议不使用正则表达式的人:
这个问题的关键是学习如何正确使用递归正则表达式.我知道这不是确定字符串是否是回文的有效方法,如果由于某种原因必须确定生产代码中的回文,我就不会使用递归正则表达式; 我只是想了解有关正则表达式高级方面的更多信息.
我不知道这是否可以使用正则表达式.我只是想问一下有人知道答案.
我有一个string ="hellohowareyou??".我需要像这样拆分它
[h, el, loh, owar, eyou?, ?].
完成分割使得第一串具有长度1,第二长度2等等.最后一个字符串将包含剩余的字符.我可以使用像这样的函数在没有正则表达式的情况下轻松完成.
public ArrayList<String> splitString(String s)
{
int cnt=0,i;
ArrayList<String> sList=new ArrayList<String>();
for(i=0;i+cnt<s.length();i=i+cnt)
{
cnt++;
sList.add(s.substring(i,i+cnt));
}
sList.add(s.substring(i,s.length()));
return sList;
}
Run Code Online (Sandbox Code Playgroud)
我只是好奇是否可以使用正则表达式完成这样的事情.
regex ×11
java ×7
palindrome ×3
c# ×2
lookaround ×2
pcre ×2
string ×2
php ×1
primes ×1
regex-greedy ×1