Java 在字符串的任意位置精确出现一个字符的正则表达式

Java 在字符串的任意位置精确出现一个字符的正则表达式,java,regex,Java,Regex,我正在编写一个Java代码,可以从任何迷宫中找到出路,我需要一个类来检查生成的迷宫。只允许使用,#,S,X字符 和#-允许在字符串的任何位置出现一次或多次 S和X-允许在字符串的任何位置出现一次且不超过一次 ^[#/.]+$-第一个条件的正则表达式, 但我无法实现第二个 迷宫输入如下所示: .......S..#. .....###.... ..X......... .-空空间、#-wall、S-start、X-exit您可以使用,像(?!…)那样编写来完成此任务,如下所示: ^(?!.*S.

我正在编写一个Java代码,可以从任何迷宫中找到出路,我需要一个类来检查生成的迷宫。只允许使用
#
S
X
字符

  • #
    -允许在字符串的任何位置出现一次或多次

  • S
    X
    -允许在字符串的任何位置出现一次且不超过一次

  • ^[#/.]+$
    -第一个条件的正则表达式, 但我无法实现第二个

    迷宫输入如下所示:

    .......S..#.
    .....###....
    ..X.........
    
    .-空空间、#-wall、S-start、X-exit

    您可以使用,像
    (?!…)
    那样编写来完成此任务,如下所示:

    ^(?!.*S.*S)(?!.*X.*X)[SX.#]+$
    

    这将使用
    ^
    [SX.#]+
    从字符串开始接受集合中的任何字符集(
    S
    )。但它拒绝任何包含2
    S
    S(
    (?!*S.*S)
    )或2
    X
    S(
    (?!*X.*X)
    )的字符串


    请注意,这实际上检查了两种情况。这里不需要2个正则表达式。不过,根据您的示例迷宫,您的输入似乎可以跨越多行。在这种情况下,您需要在最后一个字符类中添加
    \n

    如果迷宫字符串由所有行组成,您可以使用一个只声明一个S的向前看,然后只匹配一个X(或者反过来)

    在爪哇

    String regex = "^(?=[^S]*S[^S]*$)[.S#\\r\\n]*X[.S#\\r\\n]*$";
    
    解释

    • ^
      字符串的开头
    • (?=
      正向前瞻,断言右侧出现的是单个
      S
      • [^S]*S
        匹配不带
        S
        的任何字符的0+倍,匹配S
      • [^S]*$
        匹配不带
        S
        的任何字符的0+倍,字符串结尾
    • 关闭前瞻
    • [.S\r\n]*X
      匹配所有接受的字符,包括不带
      X
      的换行符,然后匹配X
    • [.S\r\n]*
      匹配所有接受的字符,包括不带
      X的换行符
    • $
      字符串结尾

    您还可以输入只允许输入一次的字符,一旦找到一个字符,请检查前面是否还有另一个字符。可能不需要多次扫描整个字符串

    ^(?:[.#]*([SX])(?!.*?\1))*[.#]*$
    

    请在所需输出的同时添加一些示例输入。通过检查循环中的每个字符,您始终可以在不使用正则表达式的情况下完成此操作。提示:每当您需要询问其他人“如何将其写入正则表达式”时。。。这可能是一个很好的迹象,表明不使用正则表达式将是更好的选择。无论如何,您都必须解释该字符串,所以为什么不用简单、独特的代码写下验证呢?
    ^(?:[.#]*([SX])(?!.*?\1))*[.#]*$