Java RegEx - 正则表达式用开始和结束分割段落
Posted
技术标签:
【中文标题】Java RegEx - 正则表达式用开始和结束分割段落【英文标题】:Java RegEx - Regular expression to split a paragraph with start and end 【发布时间】:2009-11-10 09:54:12 【问题描述】:我是 Java 正则表达式的新手。请帮助我。 考虑以下段落,
段落:
Name abc
sadghsagh
hsajdjah Name
ggggggggg
!!!
Name ggg
dfdfddfdf Name
!!!
Name hhhh
sahdgashdg Name
asjdhjasdh
sadasldkalskd
asdjhakjsdhja
!!!
我需要将以上段落拆分为以 Name 开头并以 !!! 结尾的文本块.这里我不想用!!!作为分割段落的唯一分隔符。我还需要在我的正则表达式中包含起始序列(名称)。
ie.,我的结果 api 应该看起来像 SplitAsBlocks("Paragraph","startswith Name","endswith !!!”)
如何实现这一点,请任何人帮助我......
现在我想要与 Brito 相同的输出......但是在这里我在“hsajdjah”之后添加了名称。这里将文本拆分为以下内容:
Name
ggggggggg
!!!
但我需要
Name abc
sadghsagh
hsajdjah Name
ggggggggg
!!!
也就是说,我必须匹配位于行首而不是中间的名称。
请给我建议...
Bart ...请参阅下面的输入案例以了解您的代码...
我需要使用带有参数 start => Name 和 end => 的 API 拆分以下内容! 但输出各不相同..我只有 3 个块以 Name 开头并以 ! . 我也附上了输出。
String myInput = "Name hhhhh class0"+ "\n"+
"HHHHHHHHHHHHHHHHHH"+ "\n"+
"!"+ "\n"+
"Name TTTTT TTTT"+ "\n"+
"GGGGGG UUUUU IIII"+ "\n"+
"!"+ "\n"+
"Name JJJJJ WWWW"+ "\n"+
"IIIIIIIIIIIIIIIIIIIII"+ "\n"+
"!"+ "\n"+
"RRRRRRRRRRR TTTTTTTT"+ "\n"+
"HHHHHH"+ "\n"+
"JJJJJ 1 Name class1"+ "\n"+
"LLLLL 5 Name class5"+ "\n"+
"!"+ "\n"+
"OOOOOO HHHH FFFFFF"+ "\n"+
"service 0 Name class12"+ "\n"+
"!"+ "\n"+
"JJJJJ YYYYYY 3/0"+ "\n"+
"KKKKKKK"+ "\n"+
"UUU UUU UUUUU"+ "\n"+
"QQQQQQQ"+ "\n"+
"!";
String[] tokens = tokenize(myInput, "Name", "!");
int n = 0;
for(String t : tokens)
System.out.println("---------------------------\n"+(++n)+"\n"+t);
输出:
---------------------------
1
Name hhhhh class0
HHHHHHHHHHHHHHHHHH
!
---------------------------
2
Name TTTTT TTTT
GGGGGG UUUUU IIII
!
---------------------------
3
Name JJJJJ WWWW
IIIIIIIIIIIIIIIIIIIII
!
---------------------------
4
Name class1
LLLLL 5 Name class5
!
---------------------------
5
Name class12
!
在这里我只需要在行首而不是中间的名称... 如何为此添加正则表达式...
【问题讨论】:
代码块请使用四个空格缩进。 ???Name abc sadghsagh hsajdjah Name ggggggggg !!!
正是您尝试我的建议时所得到的。你有没有尝试过我的建议?我在演示中调整了输入,当你运行它时,你会看到它产生了你刚才描述的输出。
是的,巴特我试过你的建议,它工作正常,但在特定情况下失败..我在上面的代码中添加了特定的输入情况..请看...
请注意邮件格式。
不客气unknown
。你明白尽可能清楚地表达自己是多么重要吗?在此处(或公共论坛上的任何地方)提交下一个问题之前,请校对您的问题,看看您是否可以预览您的消息发布后将如何结束:格式也很重要。祝你好运。
【参考方案1】:
试试:
import java.util.*;
import java.util.regex.*;
public class Main
public static String[] tokenize(String text, String start, String end)
// old line:
//Pattern p = Pattern.compile("(?s)"+Pattern.quote(start)+".*?"+Pattern.quote(end));
// new line:
Pattern p = Pattern.compile("(?sm)^"+Pattern.quote(start)+".*?"+Pattern.quote(end)+"$");
Matcher m = p.matcher(text);
List<String> tokens = new ArrayList<String>();
while(m.find())
tokens.add(m.group());
return tokens.toArray(new String[]);
public static void main(String[] args)
String text = "Name abc" + "\n" +
"sadghsagh" + "\n" +
"hsajdjah Name" + "\n" +
"ggggggggg" + "\n" +
"!!!" + "\n" +
"Name ggg" + "\n" +
"dfdfddfdf Name" + "\n" +
"!!!" + "\n" +
"Name hhhh" + "\n" +
"sahdgashdg Name" + "\n" +
"asjdhjasdh" + "\n" +
"sadasldkalskd" + "\n" +
"asdjhakjsdhja" + "\n" +
"!!!";
String[] tokens = tokenize(text, "Name", "!!!");
int n = 0;
for(String t : tokens)
System.out.println("---------------------------\n"+(++n)+"\n"+t);
【讨论】:
谢谢 Bart .. 我需要姓名和 !!!在我的最后一个字符串中。另外我的条件是同时使用 Name 和 !!!拆分字符串不使用 Name 或 !!! . @Kobi:不,在 Java 中,您不会在正则表达式周围使用分隔符。在这件事上不要把 Java 和 javascript 混为一谈! Bart 非常感谢您的关注...您将文本定义为单行如下... String text = "Name abc sadghsagh hsajdjah !!! Name ggg dfdfddfdf !!! Name hhhh sahdgashdg asjdhjasdh sadasldkalskd asdjhakjsdhja !!!";但在我的情况下,每个单词都在一个单独的行中..请建议我如何分割这种类型的段落? 您的意思是:return tokens.toArray(new String[tokens.size()])
?
@Bart - 抱歉,Java 当然不支持。我很困惑,确定这是 JavaScript。抱歉,不知道怎么回事……【参考方案2】:
String s = "Name abc sadghsagh hsajdjah !!! Name ggg dfdfddfdf !!! Name hhhh sahdgashdg asjdhjasdh sadasldkalskd asdjhakjsdhja !!!!! ";
String startsWith = "Name";
String endsWith = "!!!";
// non-greedily get all groups starting with Name and ending with !!!
String pattern = String.format("(%s).*?(%s)", Pattern.quote(startsWith), Pattern.quote(endsWith));
System.out.println(pattern);
Matcher m = Pattern.compile(pattern, Pattern.DOTALL).matcher(s);
while (m.find())
System.out.println(m.group());
输出:
(\QName\E).*?(\Q!!!\E)
Name abc sadghsagh hsajdjah !!!
Name ggg dfdfddfdf !!!
Name hhhh sahdgashdg asjdhjasdh sadasldkalskd asdjhakjsdhja !!!
【讨论】:
请注意,默认情况下,DOT 不匹配换行符。此外,如果 OP 想要“拆分”的子字符串包含正则表达式元字符,事情就会出错。最后,group()
与 group(0)
相同,但这只是吸引眼球。
感谢 Sfussenegger .... 如果 String s 是单行,则上述解决方案可以正常工作...但在我的情况下,它是一个段落,即,每个单词之后都有一个换行符.. .请如何拆分这个..帮助我..
您可以添加标记 s(单行模式)以使换行符与 Dotall 运算符 (.) 匹配,相关行将是 Matcher m = Pattern.compile(pattern, Pattern.DOTALL ).matcher(s);
特殊字符应该不是问题,因为我建议使用处理特殊字符的Pattern.quote(startsWith)
。此外,我编辑了我的代码以使用 group()
和 Pattern.DOTALL
。
在您编辑答案之前,我发布了有关特殊字符的评论。您的第一个答案不包含Pattern.quote(...)
's。【参考方案3】:
如果您想在结果中同时保留Name
和!!!
,也应该执行以下操作。
String[] 部分 = string.split("(?=(Name|!!!))");
编辑:这是更正的版本:
String[] parts = string.split("(?<=!!!)\\s*(?=Name)");
这将在!!!
和Name
之间的任何空白处拆分,仅此而已;特此保留这两个部分。如果您不想在 !!!Name
上拆分,请将 \\s*
替换为 \\s+
以允许一对多匹配而不是零对多匹配。
Edit2:附上输入/输出的例子。输入是从 topicstart 复制的:
String string = "Name hhhhh class0" + "\n" + "HHHHHHHHHHHHHHHHHH" + "\n" + "!" + "\n"
+ "Name TTTTT TTTT" + "\n" + "GGGGGG UUUUU IIII" + "\n" + "!" + "\n"
+ "Name JJJJJ WWWW" + "\n" + "IIIIIIIIIIIIIIIIIIIII" + "\n" + "!" + "\n"
+ "RRRRRRRRRRR TTTTTTTT" + "\n" + "HHHHHH" + "\n" + "JJJJJ 1 Name class1" + "\n"
+ "LLLLL 5 Name class5" + "\n" + "!" + "\n" + "OOOOOO HHHH FFFFFF" + "\n"
+ "service 0 Name class12" + "\n" + "!" + "\n" + "JJJJJ YYYYYY 3/0" + "\n" + "KKKKKKK"
+ "\n" + "UUU UUU UUUUU" + "\n" + "QQQQQQQ" + "\n" + "!";
String[] parts = string.split("(?<=!)\\s*(?=Name)");
for (String part : parts)
System.out.println(part);
System.out.println("---------------------------------");
输出:
Name hhhhh class0
HHHHHHHHHHHHHHHHHH
!
---------------------------------
Name TTTTT TTTT
GGGGGG UUUUU IIII
!
---------------------------------
Name JJJJJ WWWW
IIIIIIIIIIIIIIIIIIIII
!
RRRRRRRRRRR TTTTTTTT
HHHHHH
JJJJJ 1 Name class1
LLLLL 5 Name class5
!
OOOOOO HHHH FFFFFF
service 0 Name class12
!
JJJJJ YYYYYY 3/0
KKKKKKK
UUU UUU UUUUU
QQQQQQQ
!
---------------------------------
看起来不错?
【讨论】:
嗨 BalusC,你在这里使用或条件...但我需要使用和条件... 对不起,我错过了这个关键点。我会尽快更新答案。 谢谢BalusC,我已经测试了你的技巧,但是在这里请用我在我的问题中解释的上述输入测试你的代码。这里的输出不同..请看.. 是的,但是看到上面的第三个输出在我的情况下是错误的......即,我需要打破第一个!标记自己,但在上述情况下,它会显示所有行到最后...请执行 Bart 的代码并与您的输出进行比较...谢谢 BalusC 所以 .. 即使文本可能包含“!”,例如“class!0”,代码仍然应该中断吗?这对我来说似乎不合逻辑。你会更清楚地指定要求。 IE。做“!”总是在换行之前?等等。你必须考虑到一切。以上是关于Java RegEx - 正则表达式用开始和结束分割段落的主要内容,如果未能解决你的问题,请参考以下文章
java正则中REGEX = "[\u4e00-\u9fa5]+"是啥意思
用Java正则表达式来过滤Excle格式。比如Excle文件格式有.xlsx”和.xls两种。那么正则表达式怎么写呢。