如何在任意序列中搜索模式? [英] How to search patterns in arbitrary sequences?

查看:105
本文介绍了如何在任意序列中搜索模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正则表达式仅适用于字符串,但是如果该功能不仅可以扩展到字符,还可以扩展到对象甚至更多功能?
假设我们的对象是整数,它们可以是任何顺序:

Regex is on string's only, but what if that functionality can be extended to not only character but objects or even further to functions? Suppose our object's will be integers, they can be in any order:

1 2 3 4 5 6 7 8 9 10 11 12 13

您要解决的任务是找到素数对(或类似模式搜索任务),如下所示:

And the task you want to solve is to find prime pairs (or similar pattern search task) like this:

{prime}{anyNumber}{prime}

所以答案是:

(3,4,5) (5,6,7) (11,12,13)

或者是素数链的一个更复杂的例子:

Or a little more complex example for chain of primes:

{prime}({anyNumber}{prime})+

答案:

(3,(4,5),(6,7)) (11,(12,13))

非常像Regex工作,对吗?

Pretty much like Regex work, right?

你定义了一些名为 isPrime(x)<的函数会发生什么? / em>并在需要检查下一个输入元素是否为实际素数时使用它(因此它与对象或对象空间是某种相等的)

What happens is that you define some function named isPrime(x) and use it when you need to check if next input element is actualy prime (so it is some sort of equality to object or object space)

什么我到目前为止创建了

我创建了 ObjectRegex 类,类似于C#中的 Regex 类。它接受上面的模式并执行与之相关的谓词来识别对象。
它工作得很好,但问题是它可以工作任何类型的序列 TValue 应转换为字符串,然后才能传递给Regex模式和为此,我应该将所有谓词应用于整个序列。 O(n * m)毕竟是一个坏主意....

I created ObjectRegex class similar to Regex class in C#. It accepts patterns in above and execute predicate asociated with it to identify object. It works perfectly fine, but the problem is for it to work any sequence of type TValue should be converted to string before it will be passed to Regex pattern and for that I should apply ALL predicates to entire sequence. O(n*m) is a bad idea afterall....

我决定以艰难的方式解决它... ....尝试继承字符串,其中是密封的,禁止继承。这个继承类需要的是覆盖访问器

I decided to go around it the hard way and....try to inherit string, which is sealed and inheritance is forbidden. What is needed from this inherited class is override accessor

char this[int index] {get;}

将延迟执行谓词的好处转化为有意义的时刻。

for the benefit of deferred execution of predicates to moment when it actualy make sense.

那么,任何想法如何制作呢?我喜欢.NET Regex和它的语法,有没有办法绕过这个字符串诅咒和欺骗引擎?反思可能还是我不知道的一些铁杆?

So, any idea how to make it? I love .NET Regex and it's syntax, is there a way to go around this string curse and deceive engine? Reflection maybe or some hardcore I don't know?

更新1

我发现这篇文章是 http: //www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time
并认为可以通过替换此[int index]来完成我的代码的方法,但我认为它会破坏其他一切,因为你只能替换一个实例的方法。

I found this article http://www.codeproject.com/Articles/463508/NET-CLR-Injection-Modify-IL-Code-during-Run-time and think it can be done through replacement of this[int index] method by my code, but i think it will corrupt everything else, cause you just can't replace method for only one instance.

推荐答案

字符串继承



经过一番研究,我发现优化现有正则表达式的想法是不可能的。这是因为即使我知道字符串中的索引,我仍然无法访问正则表达式自动机中的可能状态,我应该尝试过滤不必要的计算。

String inheritance

After some research, I found that idea to optimize existing Regex is impossible. This is because even if I know index in string, I still don't have access to possible states in Regex automaton, which I should look to filter unneccesary calculations.

至于回答,我决定实现类似于Microsoft Regex引擎的自己的引擎。语法与Microsoft Regex语法相同。您可以在 Nuget github

As to answer, I decided to implement my own engine similar to Microsoft Regex engine. Syntax is the same as Microsoft Regex syntax. You can find more information and examples at Nuget and github:

目前,它支持基本的Regex引擎功能以及一些流行的功能,如前瞻和捕获。

Currently, it supports basic Regex engine features and also some of popular features like lookahead and capturing.

public static bool IsPrime(int number)
{
    int boundary = (int)Math.Floor(Math.Sqrt(number));
    if (number == 1) return false;
    if (number == 2) return true;
    for (int i = 2; i <= boundary; ++i)
    {
        if (number % i == 0) return false;
    }
    return true;
}

public void PrimeTest()
{
    var oregex = new ORegex<int>("{0}(.{0})*", IsPrime);
    var input = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
    foreach (var match in oregex.Matches(input))
    {
        Trace.WriteLine(string.Join(",", match.Values));
    }
}

//OUTPUT:
//2
//3,4,5,6,7
//11,12,13

这篇关于如何在任意序列中搜索模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆