2009-07-01 20 views
1

ich mich für ein Stück Code suchen, der wird:ein RE gegeben, leiten den größten Teilzeichen Spiel

Given regular expression E, derive the longest string X 
such that for every S, X is a substring of S iff S will match E 

Beispiele:

E = "a", X = "a" 
E = "^a$", X = "a" 
E = "a(b|c)", X = "a" 
E = "[ab]", X = "" 

Kontext: Ich möchte gegen einige reguläre Ausdrücke passen Ein Datenspeicher , der nur Teilstringsuche unterstützt. Es wäre nett , die Regular Expression-Suche zu optimieren, indem Sie einen Teilstring Suche in den Datenspeicher, um die Menge der übertragenen Daten so viel wie möglich zu reduzieren.

Beispiel 2:

Wenn ich "Fehler foo" fangen will, "Fehlerbalken", "Fehler baz", ich

error: (foo|bar|baz) 

und sende

search "error: " 

angeben kann in den Datenspeicher und dann erneut die zurückgegebenen Elemente.

Danke!

+1

Wenn E = "a (b | c) def", dann ist X = "def"? Die Suche nach "def" ist nicht ohne zusätzliche Informationen sofort hilfreich. Oh, und sollten alle diese "S =" "X =" sein? –

+0

(1) Ja, wenn ich den Datenspeicher veranlassen kann, nach "def" zu suchen, kann ich den regulären Ausdruck auf einen hoffentlich kleineren Datensatz anwenden. Tests an einigen handgenerierten Beispielen zeigen eine gute Beschleunigung. (2), ja, S sollte X sein, behoben, danke! –

+0

Also, was sollte für "^ [^ a] {1,10} a $" zurückgegeben werden? – Tomalak

Antwort

1

Im Allgemeinen könnten Sie versuchen, die Regex auf alle nicht eindeutigen ((a | b), [ab]) - Übereinstimmungen aufzuteilen und dann nach der längsten Zeichenfolge im resultierenden Array zu suchen. So etwas wie

$foo = longest(regex_split($regex, '(\(.*?\|.*?\))|(\[.*?\])')); 
1

Vielleicht RE auf einen endlichen Automaten umwandeln und sucht den längsten Teil, der in einem Weg zwischen Start vorhanden sein muss und beenden Staaten ... Geometrische Denken mit einer Grafik können Sie einfacher sein, zumindest ist es in meinem Fall.