java - 使用正则表达式从字符串中提取密码

标签 java regex string

我正在尝试解决一个练习,其中我必须在给定文本中打印密码。规则是:

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

Java code :

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/

相关文章:

python - 在不同的函数中使用字符串的名称

java - 在指向空异常的java中克隆对象数组

java - getClass().getResource() 异常?

regex - 查找名称匹配模式的目录并移动它们

python - 如何使用正则表达式作为字典的键?

java - 从 Java 字符串中去除前导和尾随空格

java - AssertContains 在 jUnit 中的字符串上

java - 正则表达式过滤具有多个&符号 "&"的URL

java - CXF 在 "Apache CXF"中代表什么?

regex - 可以[一个| b] 在 grep BRE 模式下使用表达式?