我正在尝试解决一个练习,其中我必须在给定文本中打印密码。规则是:
a password consists of digits and Latin upper- and lowercase letters; a password always follows the word "password" (it can be written in upper- or lowercase letters), but can be separated from it by any number of whitespaces and colon : characters.
我的问题是,我需要确保密码前面有“password”以及随机数量的空格和冒号,但我还必须仅打印密码。
例如,如果输入是:
My email <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="abc1caddcac8c4cfced9ebccc6cac2c785c8c4c6" rel="noreferrer noopener nofollow">[email protected]</a> with password SECRET115. Here is my old PASSWORD: PASS111.
输出应该是:
SECRET115
PASS111
我偶然发现了前向和后向,并在我的正则表达式中尝试了它们:
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String text = scanner.nextLine();
Pattern pattern = Pattern.compile("(?<=password[\\s:]*)\\w*(?=\\W)", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
if (!matcher.find()) {
System.out.println("No passwords found.");
}
while (matcher.find()) {
System.out.println(matcher.group());
}
}
}
此解决方案仅打印密码,但它也会无缘无故地打印额外的换行符。上述输入的输出如下所示:
SECRET115
PASS111
此外,当我尝试将正则表达式更改为 "(?<=password[\\s:]*)\\w{5,}(?=\\W)"
时因此接受的密码长度至少为 5,程序输出如下:
PASS111
另一个密码明显超过5个字符,为什么被遗漏了?
最佳答案
当您的密码正则表达式包含 \w*
时,正则表达式首先匹配空字符串。由于您在 if
条件中调用 matcher.find()
,因此不会显示此匹配项。当您使用\w{5}
时,第一个匹配项是SECRET115
,并且不会显示。
使用
\bpassword[\s:]*(\w+)
参见proof
说明
NODE EXPLANATION
--------------------------------------------------------------------------------
\b the boundary between a word char (\w) and
something that is not a word char
--------------------------------------------------------------------------------
password 'password'
--------------------------------------------------------------------------------
[\s:]* any character of: whitespace (\n, \r, \t,
\f, and " "), ':' (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
\w+ word characters (a-z, A-Z, 0-9, _) (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of \1
Scanner scanner = new Scanner(System.in);
String text = scanner.nextLine();
Pattern pattern = Pattern.compile("\\bpassword[\\s:]*(\\w+)", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
Boolean found = false;
while (matcher.find()) {
System.out.println(matcher.group(1));
found = true;
}
if (!found) {
System.out.println("No passwords found.");
}
输出:
SECRET115
PASS111
关于java - 使用正则表达式从字符串中提取密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63440612/