最佳实践:部分正则表达式匹配

8
我不确定正则表达式在这里是否是最好的解决方案,但它们似乎很合理;我只是不知道如何实际实现它。
基本上,我想让用户输入一个方法名,并在每次字符输入后对其进行有效性解析。我已经定义了一个有效的函数格式作为正则表达式,测试两个是否匹配也很容易。问题在于,我希望能够进行部分匹配,以便让用户知道“到目前为止,这是有效的”。
例如,
+(NSString *)thisIsAValid:(ObjectiveC *)method;

这是一种有效的方法。可以通过简单的正则表达式字符串进行匹配,例如

[\+-]\(w+\s*\*?\)\w+....etc...

但我希望能够使用相同的正则表达式字符串进行“匹配”

+(NSStr

我了解这有点像反向使用正则表达式。但我仍不希望正则表达式匹配到。
Q)(NStr

有没有一种使用标准正则表达式函数实现此类功能的方法,或者我必须采取更激烈的措施?
非常感谢! 您们可是无价之宝。
经过进一步的思考,我认为我可以让我的问题更加清晰(以及更加简洁):通常,人们使用正则表达式在文本中查找模式。 也就是说,在这段文字中,“cat”或“cot”出现了多少次。 我希望做相反的操作,即在正则表达式中查找字符串。也就是说,从开头开始匹配这个字符串的多少部分与这个正则表达式相匹配。 最终,我想返回字符串停止匹配所在的索引,该索引位于问号后面的位置。

看起来你真正的目标是要有一个匹配肯定是无效的模式的正则表达式,然后在匹配到该模式时触发错误。因此,你可能需要查找与语言的补集匹配的信息。请注意,正则语言的补集可能是正则的,也可能不是正则的! - Platinum Azure
沿着这条线,我建议尝试找到一个关于Objective-C语法的好描述(可能是上下文无关文法),并使用正则表达式来匹配方法声明规则的补集。 - Platinum Azure
这是一个有趣的问题,加一分! :-) - Platinum Azure
啊,现在我看到你的编辑和最终目标,想到了一个稍微不同的方法。找出每个字符串组件的正则表达式,然后逐个匹配,每次跟踪匹配了多少字符串,并在第一次失败时返回模式停止匹配的索引。换句话说,你可能需要编写一个小的“状态机”(由正则表达式表示的模式组成)。不幸的是,我完全不懂Objective-C,因此无法评论语法或具体方法。也许我会提供一个C语言的答案。 - Platinum Azure
你好,我认为最好的方法是将完整声明的正则表达式转换为D/NFA,并在模拟用户输入声明时进行模拟。但是,请注意这种方法的局限性:1)纯正则表达式无法验证所有常见的编程语言结构(例如表达式),2)通常的正则表达式引擎实际上是更强大的识别器。没有初始化和类型检查的声明应该可以正常工作,但对于您的受众可能会有限制。谢谢。 - collapsar
显示剩余5条评论
2个回答

1

RegexKit似乎使用PCRE,因此您可以尝试直接使用PCRE,因为它支持部分匹配。

#include <stdio.h>
#include <pcre.h>

void test_match(pcre *re, char *subject);

void test_match(pcre *re, char *subject) {
  int rc = pcre_exec(re, NULL, subject, (int)strlen(subject),
                     0, PCRE_PARTIAL, NULL, 0);
  printf("%s: %s\n", subject,
         rc == 0 || rc == PCRE_ERROR_PARTIAL ?
         "match or partial" : "no match");
}

int main (int argc, const char * argv[]) {
  pcre *re;
  const char *errstr;
  int erroffset;

  re = pcre_compile("^ABC$", 0, &errstr, &erroffset, NULL);
  test_match(re, "A");
  test_match(re, "AB");
  test_match(re, "ABC");
  test_match(re, "ABD");

  return 0;
}

将会打印:

A: match or partial
AB: match or partial
ABC: match or partial
ABD: no match

0

我会编写一个脚本来获取正则表达式并将其拆分,使得正则表达式 ABCD 变成新的正则表达式: ^(ABCD|ABC|AB|A)$

如果可能的话,请避免使用括号,否则您必须通过添加正确数量的闭合括号来解决这个问题。此外,您还需要通过正则表达式运算符对ABCD字符串进行标记化,以便不会拆分类似\*+之类的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接