使用垂直空白字符作为java扫描程序定界符,在每个端点扫描空字符串
我正在尝试使用Java中的Scanner类扫描一个文件,其中的数据字段由“@”或“endline”分隔。以下是一个示例输入文件:使用垂直空白字符作为java扫描程序定界符,在每个端点扫描空字符串,java,regex,java.util.scanner,Java,Regex,Java.util.scanner,我正在尝试使用Java中的Scanner类扫描一个文件,其中的数据字段由“@”或“endline”分隔。以下是一个示例输入文件: Student @ Codey @ Huntting Student @ Sarah @ Honsinger 为了正确地扫描这样的输入文件,我尝试将Java扫描程序上的分隔符更改为正则表达式“[@\\v]”,它应该匹配@或任何垂直空白,包括\n和\r,根据 下面是我用来测试它的代码: Scanner Scanner=新的扫描仪(新文件(“data/initializ
Student @ Codey @ Huntting
Student @ Sarah @ Honsinger
为了正确地扫描这样的输入文件,我尝试将Java扫描程序上的分隔符更改为正则表达式“[@\\v]”
,它应该匹配@
或任何垂直空白,包括\n
和\r
,根据
下面是我用来测试它的代码:
Scanner Scanner=新的扫描仪(新文件(“data/initialize.txt”);
int-tokenNum=0;
scanner.useDelimiter(“[@\\v]”);
while(scanner.hasNext()){
System.out.println(“Token#“+tokenNum+++”:“+scanner.next());
}
scanner.close();
我希望扫描的令牌包括:
Token #1: Student
Token #2: Codey
Token #3: Huntting
Token #4: Student
Token #5: Sarah
Token #6: Honsinger
但实际收到的代币是:
Token #1: Student
Token #2: Codey
Token #3: Huntting
Token #4
Token #5: Student
Token #6: Sarah
Token #7: Honsinger
Token #8:
我本以为扫描器在扫描hunting
时,会在搜索之后向上移动到换行符,并且在下一次调用input.next()
时,跳过该换行符,但由于某种原因,扫描器似乎在该行的末尾捕获了一个空字符串
我检查了多次,文件在任何一行之后都没有空格。我尝试过不同的模式,如
[@[\\v]]]
和[@][\\v]
,但这些模式总是给出具有相同空字符串错误的数据,或者输出完全不正常。如果我理解正确,我们可能只想删除@
和一个空格,然后将其替换为新行,并在其前面追加文本。也许,这个表达会有帮助:
([\S\s]*?)(?:@\s|$)
正则表达式
如果不需要此表达式,可以在中修改/更改表达式
正则表达式电路
您还可以在以下位置可视化您的表达式:
JavaScript演示
此代码段显示我们可能有一个有效的表达式:
const regex=/([\S\S]*?)(?:@\S|$)/gm;
const str=`Student@Codey@hunting
学生@Sarah@Honsinger`;
常量subst=`\n$1`;
//被替换的值将包含在结果变量中
const result=str.replace(regex,subst);
log('替换结果:',结果)代码>如果我理解正确,我们可能只想删除@
和后面的空格,然后用新行替换它并在它前面附加一个文本。也许,这个表达会有帮助:
([\S\s]*?)(?:@\s|$)
正则表达式
如果不需要此表达式,可以在中修改/更改表达式
正则表达式电路
您还可以在以下位置可视化您的表达式:
JavaScript演示
此代码段显示我们可能有一个有效的表达式:
const regex=/([\S\S]*?)(?:@\S|$)/gm;
const str=`Student@Codey@hunting
学生@Sarah@Honsinger`;
常量subst=`\n$1`;
//被替换的值将包含在结果变量中
const result=str.replace(regex,subst);
log('替换结果:',结果)代码>您的文件可能包含格式为\r\n
的换行符。
在这种情况下,扫描仪会找到分隔符\r
,并输出\r
之前的任何内容。然后它找到分隔符\n
,并在\r
和\n
之间输出空标记,然后在\n
之后继续
为了允许\r\n
中断,我建议您将\r\n |[@\v]
按该确切顺序作为分隔符regex。当然,在转义之后,它会变成“\r\n|[@\\v]”
正如Andreas提到的,您可以使用的另一个正则表达式是@\R
,因为\R
匹配任何unicode换行符,包括\R\n
。这可能是最好的解决方案。您的文件可能包含格式为\r\n
的换行符。
在这种情况下,扫描仪会找到分隔符\r
,并输出\r
之前的任何内容。然后它找到分隔符\n
,并在\r
和\n
之间输出空标记,然后在\n
之后继续
为了允许\r\n
中断,我建议您将\r\n |[@\v]
按该确切顺序作为分隔符regex。当然,在转义之后,它会变成“\r\n|[@\\v]”
正如Andreas提到的,您可以使用的另一个正则表达式是@\R
,因为\R
匹配任何unicode换行符,包括\R\n
。这可能是最好的解决方案。您的问题是换行符是一对\r\n
对,并且\v
分别匹配它们。为了复制这一点,让我们将代码更改为对测试数据使用内联字符串:
String input = "Student @ Codey @ Huntting\r\n" +
"Student @ Sarah @ Honsinger\r\n";
try (Scanner scanner = new Scanner(input).useDelimiter("[@\\v]")) {
for (int tokenNum = 0; scanner.hasNext(); tokenNum++) {
System.out.println("Token #" + tokenNum + ": \"" + scanner.next() + "\"");
}
}
输出
Token#0:“学生”
象征物#1:“Codey”
标记2:“狩猎”
令牌#3:“
标记4:“学生”
象征#5:“莎拉”
令牌#6:“Honsinger”
令牌#7:“
解决此问题的一种方法是首先尝试匹配\r\n
对:
useDelimiter("\r\n|[@\\v]")
输出
Token#0:“学生”
象征物#1:“Codey”
标记2:“狩猎”
标记#3:“学生”
象征4:“莎拉”
象征#5:“荣誉歌手”
但是,这将花费时间检查两次\r
,因此最好使用内置代码(任何Unicode换行符序列,相当于\u000D\u000A |[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
):
相同的结果,但更清楚地反映了您想要匹配的方式
当然,您可以使用trim()
或strip()
删除前导空格和尾随空格,但为什么不让Scanner
完成这项工作呢?使用|
需要一个(非捕获)组将其与空白匹配分开:
useDelimiter("\\s*(?:@|\\R)\\s*")
输出
Token#0:“学生”
象征物#1:“Codey”
标记2:“狩猎”
标记#3:“学生”
象征4:“莎拉”
象征#5:“荣誉歌手”
您的问题是换行符是一对\r\n
对,并且\v
分别匹配它们。答复