从 "messy" Java 字符串中提取多种数据类型
Extracting multiple Data types from "messy" Java String
我需要从文本文件中分别提取名称、年份和等级作为 String、Int 和 float。然后我用我提取的数据实例化一个 objects 列表。我缓冲了一个看起来像这样的文本字符串。
!Women Art Revolution (2010) | 3 stars, 1hr 22m
然后我在“|”处将这个字符串分成两部分字符.
String[] splitStr = line.split("|");
part1 = splitStr[0];
part2 = splitStr[1];
我计划使用扫描仪将第 1 部分中的所有 Int 收集到一个字符串中,然后抓取最后四个用于这一年。我将使用类似的方法进行评级。我的问题是获取名称字符串。 Scanner.next 似乎没有从标题名称中获取 !、数字和 () 等符号。全文文件中的标题名称不是任何看起来容易解析的特定格式。我如何为标题创建一个字符串以在我的构造函数中使用?
masterList.add(new Movie(name, year, rating));
此外,来自一些较大列表的示例(总共 10k 左右的项目):
3-Day Weekend (2008) | 2.9 stars, 1hr 23m
3:15 (U.S) (1986) | 2.9 stars, 53m
Real (2011) | 3.7 stars, 1hr 34m
Real: The Movie (2005) | 3.3 stars, 1hr 31m
等等
你为什么不使用正则表达式?
例如,正则表达式 ^!(.*) \((\d*)\) *\| *([\d.]*) *stars,.*$
将分别为您提供捕获组 1,2 和 3 中的名称、年份和评级。
更新:额外参考资料
- Java支持的regex(正则表达式)本身的语法可以参考enter link description here
- 您可以在 Java
中找到正则表达式的介绍 tutorial
这里是正则表达式本身的解释,分解成小块:
^
: 从 开始
!
:感叹号
(
: 开始捕获组 1
.*
: 任意字符出现任意次数
)
: 捕获组 1 结束
\(
: 左括号
(
:捕获组 2 开始
\d*
: 出现任意次数的数字
)
: 捕获组 2 结束
\)
: 右括号
*
:任意数量的空格
\|
: 管道字符
*
:任意数量的空格
(
: 开始捕获组 3
[\d.]*
: 任何数字或点的出现次数
)
: 捕获组 3 结束
*
:任意数量的空格
stars,
:后跟字符串 stars,
.*
:后跟任意字符出现的任意次数
$
: 直到字符串结束
示例代码:
String input = "!Women Art Revolution (2010) | 3 stars, 1hr 22m";
// mind the extra escaping of \ char because of Java string literal escaping
Pattern p = Pattern.compile("^!(.*) \((\d*)\) *\| *([\d.]*) *stars,.*$");
Matcher m = p.matcher(input);
System.out.println("matches? " + m.matches());
System.out.println("name: " + m.group(1));
System.out.println("name: " + m.group(2));
System.out.println("name: " + m.group(3));
它应该给你
matches? true
name: Women Art Revolution
name: 2010
name: 3
我需要从文本文件中分别提取名称、年份和等级作为 String、Int 和 float。然后我用我提取的数据实例化一个 objects 列表。我缓冲了一个看起来像这样的文本字符串。
!Women Art Revolution (2010) | 3 stars, 1hr 22m
然后我在“|”处将这个字符串分成两部分字符.
String[] splitStr = line.split("|");
part1 = splitStr[0];
part2 = splitStr[1];
我计划使用扫描仪将第 1 部分中的所有 Int 收集到一个字符串中,然后抓取最后四个用于这一年。我将使用类似的方法进行评级。我的问题是获取名称字符串。 Scanner.next 似乎没有从标题名称中获取 !、数字和 () 等符号。全文文件中的标题名称不是任何看起来容易解析的特定格式。我如何为标题创建一个字符串以在我的构造函数中使用?
masterList.add(new Movie(name, year, rating));
此外,来自一些较大列表的示例(总共 10k 左右的项目):
3-Day Weekend (2008) | 2.9 stars, 1hr 23m
3:15 (U.S) (1986) | 2.9 stars, 53m
Real (2011) | 3.7 stars, 1hr 34m
Real: The Movie (2005) | 3.3 stars, 1hr 31m
等等
你为什么不使用正则表达式?
例如,正则表达式 ^!(.*) \((\d*)\) *\| *([\d.]*) *stars,.*$
将分别为您提供捕获组 1,2 和 3 中的名称、年份和评级。
更新:额外参考资料
- Java支持的regex(正则表达式)本身的语法可以参考enter link description here
- 您可以在 Java 中找到正则表达式的介绍 tutorial
这里是正则表达式本身的解释,分解成小块:
^
: 从 开始
!
:感叹号(
: 开始捕获组 1.*
: 任意字符出现任意次数)
: 捕获组 1 结束\(
: 左括号(
:捕获组 2 开始\d*
: 出现任意次数的数字)
: 捕获组 2 结束\)
: 右括号*
:任意数量的空格\|
: 管道字符*
:任意数量的空格(
: 开始捕获组 3[\d.]*
: 任何数字或点的出现次数)
: 捕获组 3 结束*
:任意数量的空格stars,
:后跟字符串stars,
.*
:后跟任意字符出现的任意次数$
: 直到字符串结束
示例代码:
String input = "!Women Art Revolution (2010) | 3 stars, 1hr 22m";
// mind the extra escaping of \ char because of Java string literal escaping
Pattern p = Pattern.compile("^!(.*) \((\d*)\) *\| *([\d.]*) *stars,.*$");
Matcher m = p.matcher(input);
System.out.println("matches? " + m.matches());
System.out.println("name: " + m.group(1));
System.out.println("name: " + m.group(2));
System.out.println("name: " + m.group(3));
它应该给你
matches? true
name: Women Art Revolution
name: 2010
name: 3