我有一个String列表,我想过滤掉与正则表达式模式不匹配的String
输入列表= <head>
<script>
function draw(geo_data) {
'use strict';
var margin = 75,
width = 1920 - margin,
height = 1080 - margin;
var svg = d3.select('body')
.append('svg')
.attr('width', width + margin)
.attr('height', height + margin)
.append('g')
.attr('class', 'map');
var projection = d3.geoAlbersUsa();
var path = d3.geoPath().projection(projection);
var map = svg.selectAll('path')
.data(geo_data.features)
.enter()
.append('path')
.attr('d', path)
.style('fill', 'rgba(253, 227, 167, 0.8)')
.style('stroke', 'black')
.style('stroke-width', 0.4);
d3.csv('top100cities.csv', function(error, data) {
svg.append('g')
.attr('class', 'bubble')
.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d) {
return projection([d.lon, d.lat]);
})
.attr('cy', function(d) {
return projection([d.lon, d.lat]);
})
.attr('r', 20)
.style('fill', 'rgba(103, 65, 114, 0.5)');
});
};
</script>
</head>
<body>
<script>
d3.json('us_states.json', draw);
</script>
</body>
我的代码
Orthopedic,Orthopedic/Ortho,Length(in.)
我希望打印第2和第3个字符串,因为它们与正则表达式不匹配。但它不打印任何东西
答案 0 :(得分:3)
您没有匹配整个输入。相反,您正试图在输入中找到下一个匹配的部分。来自Matcher#find
s documentation:
尝试找到与模式匹配的输入序列的 next subsequence 。
因此,如果至少一个字符是a-zA-Z0-9-_
之一,则您的代码会匹配输入。
如果您想匹配整个地区,请使用Matcher#matches
(documentation):
尝试将整个区域与模式匹配。
您可能希望调整模式以允许多个字符,例如通过
等模式[a-zA-Z0-9-_]+
+
允许1
无限次重复模式(?
为0
至1
而*
为{{1}无限)。
您的模式结尾处有一个额外的0
。你可能想删除它。或者,如果你打算匹配字符,你需要逃脱它:
-
您可以在 regex101.com 等网站上测试您的正则表达式,这是您的模式:regex101.com/r/xvT8V0/1。
请注意,还有[a-zA-Z0-9\\-_]+
(documentation)。因此,只需使用String#matches
即可编写更紧凑的代码。
另请注意,您可以使用predefined sets快捷方式设置s.matches("[a-zA-Z0-9_]+")
等字符集。集[a-zA-Z0-9_]
(单词字符)与您想要的模式完全匹配。
由于模式和匹配器不会发生变化,您可能希望将它们移出循环以略微提高性能。
总而言之,您的所有代码可能如下所示:
\w
或紧凑:
Pattern p = Pattern.compile("[a-zA-Z0-9_]+");
Matcher m = p.matcher(s);
for (String s : keyList) {
if (!m.matches()) {
System.out.println(s);
}
}
使用流:
for (String s : keyList) {
if (!s.matches("\\w")) {
System.out.println(s);
}
}
答案 1 :(得分:1)
您不应在循环中构建Pattern
,目前只匹配单个字符,并且可以使用!String.matches(String)
和filter()
操作。像,
List<String> keyList = Arrays.asList("Orthopedic", "Orthopedic/Ortho", "Length(in.)");
keyList.stream().filter(x -> !x.matches("[a-zA-Z0-9-_]+"))
.forEachOrdered(System.out::println);
输出(根据要求)
Orthopedic/Ortho
Length(in.)
或,使用Pattern
,例如
List<String> keyList = Arrays.asList("Orthopedic", "Orthopedic/Ortho", "Length(in.)");
Pattern p = Pattern.compile("[a-zA-Z0-9-_]+");
keyList.stream().filter(x -> !p.matcher(x).matches()).forEachOrdered(System.out::println);
答案 2 :(得分:1)
有两个问题:
1)正则表达式错误,它只匹配一个字符。
2)您需要使用m.matches()
代替m.find()
。
答案 3 :(得分:0)
您可以使用matches
代替find
:
//Added the + at the end and removed the extra -
Pattern p = Pattern.compile("[a-zA-Z0-9_]+");
for(String s : keyList){
Matcher m = p.matcher(s);
if (!m.matches()){
System.out.println(s);
}
}
另请注意,编译模式的重点是重用它,所以将它放在循环之外。否则你也可以使用:
for(String s : keyList){
if (!s.matches("[a-zA-Z0-9_]+")){
System.out.println(s);
}
}