检查字符串A是否存在字符串B中任何3个连续字符的正则表达式是什么?

时间:2014-01-15 22:39:39

标签: java regex

例如: 我有一个用户名字符串:“johnwatson@221b.bakerstreet”

我想搜索一些密码字符串以确保它不包含用户名中的任何3个连续字母,例如:no“joh”,“ohn”,“hnw”等......

我知道有一种功能性方法可以做到这一点,但有没有办法用正则表达式做到这一点?

4 个答案:

答案 0 :(得分:4)

简短回答:不,您应该在应用程序代码中执行此操作,方法是生成所有3个字母的子字符串并检查密码是否包含其中任何一个。

但如果你觉得有冒险精神,你仍然可以召唤出19世纪哥特式小说中的血腥正则怪物来达到这个目的。

请参阅@ sln和@ Floris的答案。

我的2点:这是一个非常非常糟糕的主意。当你有一个固定的,规则的语法结构来识别时,正则表达式很棒,而不是你的情况。

答案 1 :(得分:1)

捕获3,消耗1
猜一猜。 Catenate用户名+换行符+密码。
(实际上不是猜测)
背景:没有点 - 所有
如果匹配,那么错误。

 # johnwatson@221b.bakerstreet\nPassword
 # (?=(...)[^\n]*\n(?:(?!\1).)*\1)


 (?=                # Lookahead assertion start
      ( . . . )          # Capture 3 non-newline chars
      [^\n]* \n          # Get up to and the next newline
      (?:                # Cluster group start
           (?! \1 )           # Backref check, not the current 3 char string in front of us
           .                  # This char is ok, consume it in the assertion context
      )*                 # Cluster group end, do 0 to many times
      \1                 # Here, found a user name sub-string 
                         #   in the password, it will match now
 )                  # Lookahead assertion end

答案 2 :(得分:1)

@ sln的答案深受启发,我想提供以下解决方案:

首先 - 将您的用户名和密码连接成一个字符串,用换行符分隔(假设换行符不会出现在用户名或密码中;我认为是合理的假设)。

接下来,使用以下表达式测试结果字符串:

(?=(...).*\n.*\1)

(见工作here

这是如何运作的:

(?=   )    - positive lookahead: "somewhere we can match this"
(...)      - three consecutive characters - 'capture group'. We can refer to these as \1
.*\n       - followed by "anything" up to a newline character
.*\1       - followed by "anything" up to a repeat of the first match (the ...)

这将尽可能努力地找到匹配(这是正则表达式尝试做的事情)。如果成功,则表示在 \n之后 部分中的\n之前发生了的三个连续字符的重复。所以试着测试一下;如果成功,你的“规则”就会被违反。

编辑 - 完整(经过测试,正在工作)的Java代码示例:

import java.io.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

class passwordTester
{
    public static void main (String[] args) throws java.lang.Exception
    {
        String username="johnwatson@221bakerstreet.com";
        String password = "youcantmakethisup";
        String input = username + "\n" + password;
        System.out.println("testing " + input);
        Pattern p = Pattern.compile("(?=(...).*\\n.*\\1)");
        Matcher m = p.matcher(input);
        if(m.find()) {
          System.out.println("the three character sequence '" + input.substring(m.start(), m.start()+3)+ "' was repeated");
        }
        else System.out.println("the password is good");
    }
}

输出:

testing johnwatson@221bakerstreet.com
youcantmakethisup
the three character sequence 'ake' was repeated

答案 3 :(得分:0)

我不这么认为。正则表达式没有“内存”,并且执行您想要的操作需要记忆先前匹配的字符。对于正则表达式的一些更邪恶的Perl扩展(内联代码?),这可能是可能的,我不确定,但我不相信这对于“纯”正则表达式是可能的。