使用垂直空白字符作为 java 扫描仪分隔符扫描每个端线上的空字符串

By simon at 2019-05-20 • 0人收藏 • 24人看过

我正在尝试用 Java 中的 Scanner 类扫描由"@"或"endline"分隔的数据字段的文件。 下面是一个示例输入文件:

学生@Codey@hunting 学生@Sarah@Honsinger

为了正确地扫描类似这样的输入文件,我尝试将 Java 扫描程序上的分隔符更改为正则表达式"[一声]",应该匹配任何@或任何垂直空格,包括什么及什么根据这一页

下面是我用来测试它的代码:

扫描器新扫描器(new Scanner (new File ("data / initialize.txt")) ; int tokenNum 0; Scanner.usedelimiter ("[@ v ]") ; 而(Scanner.hasnext ()){ System.out.println ("Token #"+ tokenNum + +":"+ Scanner.next () ; } Scanner.close () ;

我希望扫描的代币是:

代币 # 1: 学生代币 # 2: Codey 代币 # 3: hunting 代币 # 4: 学生代币 # 5: Sarah Token # 6: Honsinger

但实际接收到的令牌是:

代币 # 1: 学生代币 # 2: Codey 代币 # 3: hunting 代币 # 4: 学生代币 # 6: Sarah 代币 # 7: Honsinger 代币 # 8:

我本来期望扫描仪,扫描亨廷顿,移动到新线之后,亨廷和,在下一个电话到输入,下一个,跳过换行符,但由于某种原因,扫描器似乎在行尾抓取了一个空字符串。

我已经检查了多次,文件没有任何行后面的空格。 我尝试了不同的模式[一][]及[一][ v ],但这些总是给数据与相同的空字符串错误或输出是完全不正常的。

3 个回复 | 最后更新于 2019-05-20
2019-05-20   #1

如果我理解正确的话,我们可能只是想删除@之后是一个空格,然后用新行替换它,并在它之前追加一个文本。 也许,这个表达会有所帮助:

([ s ] * ?) (? :@ s | $)

Regex

如果不需要这个表达式,可以在Regex101. com.

正则电路

你也可以将你的表情形象化杰克斯,伊姆:

演示 JavaScript

这个片段显示了我们可能有一个有效的表达式:

Const regex / ([ s ] * ?) (? :@ s | $) / gm; const str'Student@Codey@hunting Student@Sarah@Honsinger; const subst'n $1'; / / 替换值将包含在 result 变量 const result str.replace (regex,subst) ; console.log ('Substitution result:',result) ; ;

测试

导入 java.util.regex。 4.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.2.1.1. 模式; final String regex"([ s ] *) (? @  s | $) ; final String String"Student@Codey@Huntting  n"+"Student@Sarah@Honsinger"; final String subst"$1 n"; final Pattern Pattern Pattern pile (regex,Pattern.multiline) ; final Matcher Matcher Pattern.Matcher (String) ; / / The Substitution value 将包含在 result variable final String result Matcher.replaceall (subst) ; System.out.println ("result:"+ Substitution result) ;

如果我们希望删除新的代码行,我们可以将其添加到第二个捕获组中,这样问题就可以得到解决:

([ s ] + ?) (@ s |  n  s | | | | $)

在这里,在第二个捕获组(@ s | n s | | | | $),使用逻辑 OR,我们可以排除我们不希望拥有的字符:

演示

Const regex / ([ s  s ] + ?) (@ s |  n | n | | | | $) / gm; const str'Student@Codey@hunting Student@Sarah@Honsinger; const subst'Token # : $1 n'; / / 替换值将包含在 result 变量 const result str.replace (regex,subst) ; console.log ('Substitution result:',result) ; ;

测试

导入 java.util.regex。 4.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.2.1.1. 模式; final String regex"([ s  s ] + ?) 最终字符串"Student@Codey@Huntting  n  n"+"Student@Sarah@Honsinger  n"; 最终字符串子句"Token # : $1 n"; final Pattern Pattern Pattern pile (regex,Pattern.multiline) ; final Matcher Matcher n.Matcher (String) ; / / 替换值将包含在结果变量 String result Matcher.replaceall (subst) ; system.out.tln ("Substitution result:"+ result) ;
2019-05-20   #2

您的文件可能包含表单的换行符怎么了. 在这种情况下,您的扫描仪将查找分隔符什么输出任何东西什么. 然后找到分隔符什么之间的空标记输出什么及什么然后继续什么.

允许怎么了休息,我建议你采取[一声]会怎么样作为分隔符 regex。 当然,这会变成"[一] n"逃跑之后。

2019-05-20   #3

你的问题是换行符是一个怎么了一对,然后什么单独匹配。 为了复制这一点,让我们改变你的代码,使用一个内联字符串作为测试数据:

字符串输入"Student@Codey@Huntting  r  n"+"Student@Sarah@Honsinger  r  n"; 尝试(Scanner new Scanner (input)。 { for (int tokenNum 0; scanner.hasNext () ; tokenNum +)){ System.out.println ("Token #"+ tokenNum +": "+ scanner.next () +"") ; }

输出

令牌 # 0:"学生"令牌 # 1:"Codey"令牌 # 2:"hunting"令牌 # 3:"令牌 # 4:"学生"令牌 # 5:"Sarah"令牌 # 6:"Honsinger"令牌 # 7:

解决这个问题的一个方法是尝试匹配怎么了先配对

Usedelimiiter (" r  n | [@ v ]")

输出

标记 # 0:"学生"标记 # 1:"Codey"标记 # 2:"hunting"标记 # 3:"学生"标记 # 4:"Sarah"标记 # 5:"Honsinger"

然而,这将花费时间检查什么两次,所以最好使用内置的R(任何 Unicode 换行符序列,相当于U000d u000A | u000B u000C u000D u0085 u2028 u2029]):

Usedelimiiter ("@|  r")

同样的结果,但更清楚地反映了你想如何匹配。


你当然可以使用配平()或脱衣服()删除前导和尾随空格,但为什么不使用扫描仪干活吗? 使用|需要一个(非捕获)组将其与空白匹配分开:

Usedelimit (" s * (? :@|  r) s *")

输出

令牌 # 0:"学生"令牌 # 1:"Codey"令牌 # 2:"Huntting"令牌 # 3:"学生"令牌 # 4:"Sarah"令牌 # 5:"Honsinger"

登录后方可回帖

Loading...