0

我有以下代码,试图匹配增加*计数的金字塔,两边都有相同数量的空格。

//pyramid
var p = "     *     \n" +
        "    ***    \n" +
        "   *****   \n" +
        "  *******  \n" +
        " ********* \n" +
        "***********\n";
//not a pyramid - rows 2 and 3 do not increase in width
var np = "     *     \n" +
         "   *****   \n" +
         "   *****   \n" +
         "  *******  \n" +
         " ********* \n" +
         "***********\n";
//pyramid with more width variation, non-point top
var pspace = "          **          \n" +
             "         ****         \n" +
             "      **********      \n" +
             "    **************    \n" +
             "   ****************   \n" +
             "**********************\n";
final var REGEX = "((?<S>\\s*)(?<star>\\**)\\k<S>\\R(?=$|((?<S2>\\s*)(?<extra>\\*+)\\k<star>\\k<extra>\\k<S2>\\R)))+";
System.out.println("p is a pyramid: "+Pattern.matches(REGEX, p));
System.out.println("np is a pyramid: "+Pattern.matches(REGEX, np));
System.out.println("pspace is a pyramid: "+Pattern.matches(REGEX, pspace));

输出:

p 是金字塔:真
np 是金字塔:假
pspace 是金字塔:真

我要做的最后一件事是确保输入字符串的所有“行”长度相等。在这一点上,我完全被卡住了,因为除了固定长度的字符串边界(即)之外我真的找不到任何东西X{min, max}。所以,这就是我想知道的:

  1. 如何确保我的字符串中的所有行都是金字塔(从第一行到最后一行增加星数(完成),用新行分隔(完成),在空格内居中(完成),等长线( ???))?
  2. 如何简化正则表达式以减少命名捕获组的过度使用?
4

1 回答 1

0

正则表达式无法完成您尝试完成的计数类型,因此您必须使用混合策略。在换行符边界上分解字符串,然后使用正则表达式匹配前导和尾随空格以及它们之间的星号。但是您必须通过查看这些字符串使用对象拥有的length方法的时间长度来查看这些匹配项的长度是否满足您的要求:String

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

public class test
{
    public static void main(String[] args) {
        String p = "     *     \n" +
                   "    ***    \n" +
                   "   *****   \n" +
                   "  *******  \n" +
                   " ********* \n" +
                   "***********\n";
        String[] lines = p.split("\n");
        Pattern pattern = Pattern.compile("^(\\s*)(\\*+)(\\s*)$");
        int lastLength = 0;
        boolean isPyramid = true;
        for (String line : lines) {
            Matcher m = pattern.matcher(line);
            m.find();
            String spaces1 = m.group(1);
            String spaces2 = m.group(3);
            String asterisks = m.group(2);
            int len = asterisks.length();
            if (len <= lastLength || spaces1.length() != spaces2.length()) {
                isPyramid = false;
                break;
            }
            else {
                lastLength = len;
            }
        }
        System.out.println("p is a pyramid: " + isPyramid);    
    }
}
于 2019-08-22T02:53:58.330 回答