我必须解析一个字符串并捕获一些值:
FREQ = WEEKLY; WKST = MO; BYDAY = 2TU,2WE
我想拍摄两组:
grp 1: 2, 2
grp 2: TU, WE
数字代表间隔。 TU,WE代表工作日。我需要两个。
我正在使用此代码:
private final static java.util.regex.Pattern regBYDAY = java.util.regex.Pattern.compile(".*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*");
String rrule = "FREQ=WEEKLY;WKST=MO;BYDAY=2TU,2WE";
java.util.regex.Matcher result = regBYDAY.matcher(rrule);
if (result.matches())
{
int grpCount = result.groupCount();
for (int i = 1; i < grpCount; i++)
{
String g = result.group(i);
...
}
}
grpCount == 2 - 为什么?如果我正确阅读了java文档(那一点点)我应该得到5? 0 =整个表达式,1,2,3,4 =我的捕获2,2,TU和WE。
result.group(1)==“2”;
我是一名几乎没有Java经验的C#程序员,因此我在“正则表达式工作台”中测试了RegEx,这是一个用于测试RegEx的优秀C#程序。我的RegEx工作正常。
https://code.msdn.microsoft.com/RegexWorkbench
RegExWB:
.*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*
Matching:
FREQ=WEEKLY;WKST=MO;BYDAY=22TU,-2WE,+223FR
1 => 22
1 => -2
1 => +223
2 => TU
2 => WE
2 => FR
答案 0 :(得分:1)
您也可以使用这种方法来提高可读性,并使用更常见的正则表达式子集来实现某些点独立性
final Pattern re1 = Pattern.compile(".*;BYDAY=(.*)");
final Pattern re2 = Pattern.compile("(?:([+-]?[0-9]*)([A-Z]{2}),?)");
final Matcher matcher1 = re1.matcher(rrule);
if ( matcher1.matches() ) {
final String group1 = matcher1.group(1);
Matcher matcher2 = re2.matcher(group1);
while(matcher2.find()) {
System.out.println("group: " + matcher2.group(1) + " " +
matcher2.group(2));
}
}
答案 1 :(得分:1)
你的正则表达式在Java中的工作方式与在C#中的工作方式相同;只是在Java中,您只能访问每个组的最终捕获。事实上,.NET是我所知道的仅有的两种正则表达式之一,它可以让您检索中间捕获(Perl 6是另一种)。
这可能是在Java中执行所需操作的最简单方法:
String s= "FREQ=WEEKLY;WKST=MO;BYDAY=22TU,-2WE,+223FR";
Pattern p = Pattern.compile("(?:;BYDAY=|,)([+-]?[0-9]+)([A-Z]{2})");
Matcher m = p.matcher(s);
while (m.find())
{
System.out.printf("Interval: %5s, Day of Week: %s%n",
m.group(1), m.group(2));
}
以下是等效的C#代码,如果您有兴趣:
string s = "FREQ=WEEKLY;WKST=MO;BYDAY=22TU,-2WE,+223FR";
Regex r = new Regex(@"(?:;BYDAY=|,)([+-]?[0-9]+)([A-Z]{2})");
foreach (Match m in r.Matches(s))
{
Console.WriteLine("Interval: {0,5}, Day of Week: {1}",
m.Groups[1], m.Groups[2]);
}
答案 2 :(得分:0)
我有点生疏,但我会建议“警告”。首先,regexp(s)有各种方言。有一本关于此的精彩O'Reilly书,但您的C#实用程序可能会应用略有不同的规则。
作为一个例子,我使用了一个类似的(但不同的tool)并发现它确实解析了不同的东西......
首先它拒绝了你的正则表达式(也许是一个错字?),初始的“*”没有意义,除非你在它前面放一个点(。)。像这样:
.*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*
现在它已被接受,但它“仅匹配”2 / WE部分,并“跳过”2 / TU对。
(我建议你阅读贪婪和非贪婪的匹配,以便更好地理解这一点。
因此,我按如下方式更新了您的模式:
.*;BYDAY=(?:([+-]?[0-9]*)([A-Z]{2}),?),(?:([+-]?[0-9]*)([A-Z]{2}),?)*.*
现在它可以正常捕获2,TU,2和WE。
也许这有帮助?