我正在尝试在表示为字符串的2D矩阵中搜索模式。请注意以下内容:
// horizontal line
String pat1 =
"............." +
"............." +
"............." +
"....XXXX....." +
"............." +
".............";
// vertical line
String pat2 =
"............." +
"......X......" +
"......X......" +
"......X......" +
"......X......" +
".............";
搜索第一个模式将是微不足道的,正则表达式将是这样的:
X+
在第二种情况下,它有点棘手但可行,因为我知道矩阵的列数和行数:
(X.{`WIDTH - 1`})+
当我遇到问题想出正确的正则表达式时,试图想出一种识别以下模式的方法:
// fixed but unknown number of columns
String pat3 =
"............." +
".....XXX....." +
".....XXX....." +
".....XXX....." +
".....XXX....." +
".............";
// variable number of columns
String pat4 =
"............." +
".....XXX....." +
"....XXXXX...." +
"...XXXXXXX..." +
".....XXX....." +
".............";
我正在寻找的是一种创建等同于:
的正则表达式模式的方法(X.{`WIDTH - PREVCOUNT`})+
PREVCOUNT
是最后匹配模式的长度(我知道我会错过pat4中第4行的第一个X,但我可以忍受它)。我知道正则表达式中存在前瞻性,但我想知道我想要实现的目标是否可行。即使有可能,我也担心使用前瞻的性能,因为我不完全了解它们如何在内部工作。
有没有一种方法可以通过单一的正则表达式验证来实现,或者我必须逐行搜索,然后尝试查看X是否都是连续的?
编辑:作为澄清,我正在尝试搜索X的“blob”。只要在列/行之间存在连续的X,就可以将其视为属于blob。几个例子:
String blob1 =
"............." +
"......XX....." +
"....XXXX....." +
"...XXXXX....." +
".....XXX....." +
".............";
String blob2 =
"............." +
".....XXX....." +
"....XXXXX....." +
"...XXXXXXX..." +
"....XXXXX...." +
".....XXX.....";
String blob3 =
"............." +
".....XXX....." +
".....XXX......" +
".....XXX....." +
"............." +
".............";
String notblob =
"............." +
"..XXX........" +
"......XXX....." +
"..XXX........." +
".............." +
".............";
我的解决方案不需要精确,因此我尝试使用可能糟糕的正则表达式方法。
答案 0 :(得分:2)
基本上,您可以定义矩阵:
0^k1 X^l1 0^m1
0^k2 X^l2 0^m2
0^k3 X^l3 0^m3
000XX000
^ ^ ^
k l m
其中,0 ^ a表示“字符'0'重复一次”,
k代表X
之前重复0
l代表重复X
m代表X
之后重复0
ki + li + mi = row_width,对于任何i
现在,您的blob标准是:
mi + k(i+1) < row_width
ki + m(i+1) < row_width
these two conditions should meet for any i
常规语言无法与这种模式匹配,它们没有内存,因此没有正则表达式解决方案来解决您的问题。
正确的解决方案将涉及连接组件计数,以确定有多少单独的组件。
答案 1 :(得分:1)
我认为一个优雅的解决方案是首先抑制水平和垂直的所有单X序列,例如:
String blob = ".....";
blob.replaceAll("([^X])X([^X])", "$1.$2")
.replaceAll("([^X].....)X(.....[^X])","$1.$2");
然后,至少2个Xes的所有剩余序列都是斑点。 请注意,为了克服sdanzig提到的相同问题,您应首先使用非Xes的“边框”“展开”blob。
答案 2 :(得分:0)
我想我想知道你在这里要做什么。您定义的“prevcount”不足以匹配模式。您必须考虑“下一个宽度”才能确定要检查的点数。但是,我不确定你是否真的在验证那些微不足道的模式。 X +也将连续匹配5个X.在你的第二个模式中,第一行或最后一行可能是两个X,你就不会发现它。
那就是说,这是一种用pat3提供类似验证的方法:
(X{3}.{`WIDTH-3`})+
我可能通过重复X模式打破了另一个禁忌,但你需要这样做才能使重复模式与“X-block”的开始和停止保持一致。
pat4甚至比较棘手。没有真正的方法来保持您的验证顺序一次检查一行。你可以这样做:
(X{3}.{`WIDTH-4`}|X{5}.{`WIDTH-6`}|X{5}.{`WIDTH-6`}|X{3}.{`WIDTH-5`})+
但是你很容易在切换行的情况下验证矩阵,并且在X块的每一侧都改变了点以适应。但是,您可以尝试一次检查所有行:
(X{3}.{`WIDTH-4`}X{5}.{`WIDTH-6`}X{5}.{`WIDTH-6`}X{3}.{`WIDTH-5`})
这不会有任何额外的性能损失。它可能更有效率,因为你只会产生一次启动正则表达式模式编译+匹配的开销。
琐碎的旁注: 如果您使用矩阵的宽度作为多行字符串,它将无法工作。您需要添加一个,以考虑换行符。然后你需要确保你的“。”捕获换行符也是如此。在Java中,您可以使用Pattern.DOTALL。