Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在正则表达式上拆分并在Java中捕获匹配的分隔符表达式?_Java_Regex_String_Split - Fatal编程技术网

在正则表达式上拆分并在Java中捕获匹配的分隔符表达式?

在正则表达式上拆分并在Java中捕获匹配的分隔符表达式?,java,regex,string,split,Java,Regex,String,Split,我试图解析一个文本文件,它有一系列“记录”,以一个数字开头(后面是一个字母和1-2个空格),包含数百个字母和数字,跨越换行符,但不会以任何可预测的结尾。标识记录结尾的唯一方法是点击起始标记的下一个实例,该实例可由以下正则表达式匹配: \\d{1,4}\\u00A0\\s+ 内容是手工输入的,有不可预测的换行符,所以我把它们删掉了。这给我留下了一条线索 1 blah blah blah 2 blah blah blah ... 875 blah blah blah 因为我知道一个记

我试图解析一个文本文件,它有一系列“记录”,以一个数字开头(后面是一个字母和1-2个空格),包含数百个字母和数字,跨越换行符,但不会以任何可预测的结尾。标识记录结尾的唯一方法是点击起始标记的下一个实例,该实例可由以下正则表达式匹配:

\\d{1,4}\\u00A0\\s+ 
内容是手工输入的,有不可预测的换行符,所以我把它们删掉了。这给我留下了一条线索

1  blah blah blah  2  blah blah blah ... 875  blah blah blah 
因为我知道一个记录已经结束的唯一方法是点击下一个记录ID,所以我尝试在上面的正则表达式上拆分。这会将文件正确地拆分为记录,但会忽略我需要捕获的记录ID。我检查了Java文档,但是没有关于捕获正在拆分的动态值的任何内容。我尝试将记录编号设置为捕获组,但该数据不会保留在生成的数组中

这个问题()看起来很相似,但提问者知道每个文本片段的结尾;而我只知道每一个都从哪里开始

那么,是否有其他方法可以拆分,但通过拆分正则表达式保留文本匹配

谢谢,不要使用
split()
,而是编写自己的正则表达式循环,例如

String input = "...your input...";
Matcher m = Pattern.compile("\\d{1,4}\\u00A0\\s+").matcher(input);
int prev = 0;
while (m.find()) {
    String prevText = input.substring(prev, m.start());
    prev = m.end();
    String delimiter = m.group();
    // ... code here ...
}
String tailText = input.substring(prev); // text after last delimiter
// ... code here ...
不要使用
split()
,而是编写自己的正则表达式循环,例如

String input = "...your input...";
Matcher m = Pattern.compile("\\d{1,4}\\u00A0\\s+").matcher(input);
int prev = 0;
while (m.find()) {
    String prevText = input.substring(prev, m.start());
    prev = m.end();
    String delimiter = m.group();
    // ... code here ...
}
String tailText = input.substring(prev); // text after last delimiter
// ... code here ...

如果您只想检查文本后是否存在其他文本,但未在匹配中包含该文本(如检查
foo
后是否为
bar
,但未在匹配中包含
bar
),则您正在寻找或更准确、积极的前瞻
(?=…)

因此,让我们从
split((?=\\d{1,4}\\u00A0\\s+)
开始。这将在后面有NBSP和一些空格的任何1-4位数序列之前分割。这方面的问题是,对于像

1234[nbsp]___ 
这说明了位置(用
|
标记)

但我们不想允许数字之间的分割。我们必须增加条件以防止这种分裂。所以,如果我们能说“拆分位置之前不能有数字”,那就太好了。要做到这一点,我们可以使用负数look-behind
(?),在我们的例子中,负数look-behind类似于
(?)

所以最终的解决方案看起来像:

split("(?<!\\d)(?=\\d{1,4}\\u00A0\\s+)")

split((?如果您只想检查您的文本后是否存在其他文本,但未在匹配中包含该文本(例如检查
foo
后是否为
bar
但未在匹配中包含
bar
),那么您正在寻找或更准确地说,积极地向前看
(?=…)

因此,让我们从
拆分((?=\\d{1,4}\\u00A0\\s+)
开始。这将在后面有NBSP和一些空格的任何1-4位数字序列之前拆分。这是一个类似文本的问题

1234[nbsp]___ 
这说明了位置(用
|
标记)

但我们不希望允许数字之间的拆分。我们必须添加条件以防止此类拆分。因此,如果我们可以说“拆分位置之前不能有数字”,那就太好了。为此,我们可以使用负数look behind
(?在我们的情况下,它看起来像
(?)

所以最终的解决方案看起来像:

split("(?<!\\d)(?=\\d{1,4}\\u00A0\\s+)")

split((?Variant:
Pattern.compile((.*)(\\d{1,4}\\u00A0\\s+),Pattern.DOTALL);while(m.find()){String prevText=m.group(1);String delimiter=m.group(2);…}
。或者,如果您关心末尾的未终止位:
String delimiter;Pattern.compile((.**(\\d{1,4}\\u00A0+\\ s+))”),Pattern.DOTALL);while(分隔符){m.find();字符串prevText=m.group(1);分隔符=m.group(2);…}
@DavidKnipe第一部分是无用的,因为您肯定关心尾部文本,因为分隔符是前缀,而不是终止符。--对于第二部分,您只是导致了一个
IllegalStateException
,因为在
find()之后调用时会发生这种情况
返回false。在javadoc中就是这样说的。--好吧,我的意思是,这就是在某种程度上修复了未初始化的
分隔符的编译错误后会发生的情况。
find()
不应该返回false,因为我在正则表达式中添加了
$
,所以它应该在末尾匹配,没有分隔符。并且将
字符串分隔符;
更改为
字符串分隔符=null;
。变量:
模式。编译((.*)(\\d{1,4}\\u00A0\\s+)、模式.DOTALL);而(m.find(){String prevText=m.group(1);String delimiter=m.group(2);…}
。或者,如果您关心结尾处的未终止位:
字符串delimiter;Pattern.compile((.*)(\\d{1,4}\\u00A0\\s+|$)、Pattern.DOTALL);while(!“”.equals(delimiter)){m.find();String prevText=m.group(1);delimiter=m.group(2);}
@DavidKnipe第一部分是无用的,因为您肯定关心尾部文本,因为分隔符是前缀,而不是终止符。--对于第二部分,您只是导致了一个
IllegalStateException
,因为在
find()之后调用时会发生这种情况
返回false。在javadoc中就是这样说的。--好吧,我的意思是,这就是在某种程度上修复了未初始化的
分隔符的编译错误后会发生的情况。
find()
不应该返回false,因为我在正则表达式中添加了
$
,所以它应该在末尾匹配,没有分隔符。并且将
字符串分隔符;
更改为
字符串分隔符=null;
。啊。非常好。对于后代来说:这种拆分方法允许我在每个s中保留正则表达式匹配的动态分隔符plit line.Ah.非常好。对于后代来说:这种拆分方法允许我在每个拆分行中保留正则表达式匹配的动态分隔符。