我想使用正则表达式从以下输入中提取名称。
Student Names:
Name1
Name2
Name3
Parent Names:
Name1
Name2
Name3
我使用以下方法来匹配数据,我不应该修改方法。我必须提出适用于此方法的正则表达式。
public void parseName(String patternRegX){
Pattern patternDomainStatus = Pattern.compile(patternRegX);
Matcher matcherName = patternName.matcher(inputString);
List<String> tmp=new ArrayList<String>();
while (matcherName.find()){
if (!matcherName.group(2).isEmpty())
tmp.add(matcherName.group(2));
}
}
我想出了一个正则表达式,可以得到我想要的结果,但我发现的问题是分组在方括号([])中不起作用。
private String studentRegX =“(学生姓名:\ n [+ (\ S +) \ n] + \ n)”;
我现在正在使用以下正则表达式,但这只是我每个集合中的姓氏。
private String studentRegX="Student Names:\\n( +(\\S+)\\n)+\\n"; private String parentRegX="Parent Names:\\n( +(\\S+)\\n)+\\n";
提前感谢您的帮助。
答案 0 :(得分:0)
首先,我希望您可以稍微更改parseName
方法,因为它不会编译。 patternDomainStatus
和patternName
可能应该引用同一个对象:
Pattern pattern = Pattern.compile(patternRegX);
Matcher matcherName = pattern.matcher(inputString);
其次,你需要以不同的方式考虑你的正则表达式。
现在,你的正则表达式试图匹配整个块中的多个名称。但是matcherName.find()
找到&#34;输入序列的下一个子序列与模式匹配&#34; (根据javadoc)。
所以你想要的是匹配单个名称的正则表达式。 matcherName.find()
将循环遍历与该正则表达式匹配的字符串的每个部分。
答案 1 :(得分:0)
如果您还不熟悉重复捕获组和捕获重复组之间的区别,那么值得一读。其中一个资源是http://www.regular-expressions.info/captureall.html,但其他资源也可以。
如果你已经知道了这个差异,并试图捕捉一个重复的群体已经与你上面写的内容,那么请编辑你的帖子来解释你想要做什么(逐个字母的解释会是理想的,所以我们看到你理解的和你不理解的东西,所以我们可以帮助你解决任何问题。
我看到我认为的解决方案,但由于这显然是家庭作业,我不愿意简单地给你。但我很乐意帮助你搞清楚。
---编辑:---
您只获得一场比赛,因为正则表达式要求“学生姓名:”或“家长姓名:”在每次匹配中,因此您只能匹配一次。为了让你的正则表达式连续多次匹配(根据while (matcherName.find())
的要求),你需要从正则表达式中获取“学生姓名:”和“父姓名:”,这样正则表达式可以重复匹配。
很容易获得所有名称(学生和家长),只需要一个正则表达式,查找换行符后跟一个或多个空格然后是文本。挑战在于区分学生姓名(位于“父姓名:”行之前)和父姓名(位于“父姓名:”行之后)。区分它们的关键概念是lookaheads,它可以是正面的,也可以是负面的。看看它们,看看你是否可以找出如何使用前瞻实现这一点。
此外,您可能会发现组#2不是您真正想要使用的组。不幸的是,组号是硬编码的,但是既然如此,你可以调整你的正则表达式,使用(?:stuff)
语法使组不能被捕获。这样可以减少组的数量,并确保您真正想要的组是#2。
答案 2 :(得分:0)
因为正则表达式与算法能力关系不大,所以答案是:
然后
Pattern.compile("(?s)(?<=\n)[ \t]+([^\r\n]*)\r?\n(?=.*Parent Names)");
// ~~~~ '.' also matches newline
// ~~~~~~~ look-behind must be newline
// ~~~~~~ whitespace (spaces/tabs)
// ~~~~~~~~~~ group 1, name
// ~~~~~~~~~~~~~~~~~~~~ look-ahead
不用说,有点不同的算法会更加稳固和可理解。
要使其成为组(2)而不是上述组(1),您可以在之前引入额外的大括号:([ \t]+)
答案 3 :(得分:0)
可以在单个正则表达式中使用\G
锚点来完成
这为一个小的正则表达式算法实力打开了它。
每场比赛将是:
在所有情况下,第3组将包含一个已经修剪并准备放入数组的名称。
# "~(?mi-)(?:(?!\\A)\\G|^(?:(Student)|(Parent))[ ]Names:)\\s*^(?!(?:Student|Parent)[ ]Names:)[^\\S\\r\\n]*(.+?)[^\\S\\r\\n]*$~"
(?xmi-) # Inline 'Expanded, multiline, case insensitive' modifiers
(?:
(?! \A ) # Here, matched before, give Name a first chance
\G # to match again.
|
^ # BOL
(?:
( Student ) # (1), New 'Student' group
| ( Parent ) # (2), New 'Parent' group
)
[ ] Names:
)
# Name section
\s* # Consume all whitespace up until the start of a Name line
^ # BOL
(?!
(?: Student | Parent ) # Names only, Not the start of Student/Parent group here
[ ] Names:
)
[^\S\r\n]* # Trim leading whitespace ( can use \h if supported )
( .+? ) # (3), the Name
[^\S\r\n]* # Trim trailing whitespace ( can use \h if supported )
$ # EOL