5

我一直在努力寻找实现我的系统的好方法,该系统基本上与字符串中的节目的季节和剧集编号相匹配,您可以在此处查看当前的工作代码:https ://github.com/huddy/tvfilename

我目前正在重写这个库,并想要一种更好的方式来实现匹配的发生方式,目前它的工作方式基本上是:

有一个包含类的文件夹(称为处理程序),每个处理程序都是一个实现接口以确保调用 match() 方法的类;存在,此匹配方法使用存储在该处理程序类(其中有很多)的属性中的正则表达式来尝试匹配季节和剧集。

该类通过将每个处理程序实例化为存储在属性中的数组来加载所有这些处理程序,当我想尝试匹配一些字符串时,该方法将遍历这些对象调用 match(); 然后返回第一个返回 true 的结果集,其中包含与之匹配的季节和剧集。

我真的不喜欢这种方式,这对我来说有点 hacky,我希望设计模式可以提供帮助,我的最终目标是使用最佳实践来做到这一点,我想知道我应该使用哪一个?

存在的其他问题是:

  • 多个处理程序可以匹配一个字符串,因此它们必须是为了防止更贪婪的那些首先匹配,不确定这是否可以解决,因为某些正则表达式模式必须是贪婪的,但可能是一个评分系统,某事这显示了匹配正确可能性的百分比,但我不知道如何实际实现这一点。

  • 如果实例化所有这些处理程序是一种好方法,我不是,速度很重要,但使用最佳实践和坚持设计模式来创建好的、可扩展和可维护的代码是我的最终优先事项。值得注意的是,处理程序类有时会做其他事情,而不仅仅是正则表达式匹配,它们有时会通过删除常用词等来准备要匹配的字符串。

为任何帮助而欢呼比利

4

4 回答 4

2

为每个正则表达式创建一个类非常低效,您在这里将类与数据混淆。您可以将所有正则表达式存储在配置数组或单独的类或 XML 文件中 - 没关系。然后一个方法可以接受所有正则表达式,遍历它们并执行匹配。如果一个季节并不总是匹配[1],您可以使用命名子模式 - 这将解决该问题。

至于您的模式顺序问题,您可以简单地将所有模式按您喜欢的顺序排列 - 从最具体的模式到更一般的模式。

于 2012-07-01T18:29:20.370 回答
1

您可以调整此模式以实现对 PHP的复杂案例分析。这或多或少是你一直在做的事情。您定义所有案例,实现一个条件,说明案例何时适用,以及当您在该案例中时如何解决问题。该模式将允许您决定在多个案例适用时该怎么做(选择一个,优先考虑另一个,或者任何您想要的)。

如果您将格式命名为 S01E01 之类的更好的格式,我也是一个好主意

SddEdd
SnnEnn
SDigitDigitEDigitDigit
STwoDigitsETWoDigits

而不是格式1,格式2。您还可以稍微修改模式以针对案例的条件和解决方案使用对象实例,因此您将能够使用单个类 new RegexpCase("S(?:\d{ 2})E(?:\d{2})"); 以及所有其他不只是带有类的正则表达式来解决该案例的案例。

于 2012-07-03T00:25:52.887 回答
0

我认为您需要根据您想要的参数为您的模式顺序设置一个偏好顺序。我认为第二个答案确实很好地回答了您的问题。而且您的代码似乎做得很好。看起来写得很好

于 2012-07-04T07:18:38.823 回答
0

我个人更喜欢在这种情况下使用单独的类,如果您采用这种方法(即,如果您确实需要操作字符串),您的代码库将更加灵活。如果您看一下 Zend 如何实现 Zend_Validate 和 Zend_Filter ,它们与当前实现有一个非常相似的方法(循环在类上运行 ->validate() 和 ->filter() 的属性)。

我会有一个类似于这样的结构:

  • App_Tv_Match
  • App_Tv_Match_Abstract
  • App_Tv_Match_Collection
  • App_Tv_Match_SXXXXX
  • App_Tv_Match_SeasonXEpisodeX

(但是,您的命名可能会激怒这些课程)。

但是,在摘要中,我将有一个类似于此的设置:

Abstract Class App_Tv_Match_Abstract
{
     protected $_returnOnMatch = false;
     protected $_priority      = 1;
}

我的 App_Tv_Match_Collection 类将注入匹配类 - 然后集合类将使用匹配类处理排序和匹配。如果 Match 类将“returnOnMatch”标记为 true,那么如果匹配,我将停止尝试并返回这个(即对于非贪婪的),但是如果没有匹配的 returnOnMatch 类,那么我将返回具有最高优先级的那个(或者使用排序,或集合类中的简单循环)。

于 2012-07-20T09:23:00.237 回答