1

我正在尝试为我被要求做的工作制作一个正则表达式,但我没有运气让它足够高效。
目标是使以下内容尽可能高效。
目标编号 1. 使用句子结尾(点、3 个点、感叹号...)分隔所有文本。
目标数字 2 获取出现在字符串 'em' 之后的所有数字 这
是一个可能的小字符串的示例及其正则表达式。(真正的可能真的很笨拙)
正则表达式:旧:
(?:[^.!?:]|...)(?:(?:[^.!?:]|...)*?em (\d+))*
新:
(?:[.!?]|[.][.][.])(?:(?:[^.!?]|[.][.][.])*?\bem\b (\d+))*

适用于字符串(我只是编造的)
(我在开头插入 . )

.Foi visto que a batalha em 1939 foi。Claro que a data que digo ser em 1939 é uma farsa。Em 1938 já(插入 em 1910)não havia reis。

我想要的是制作一个不回溯的正则表达式,因为它根本不需要回溯。通过这样做,我想我可以节省这需要的处理时间……从 30 秒减少到 20 秒甚至 10 秒!就为了这个1,需要1s才能完成。
补充:
谢谢现在的答案,我有一个不会失败的答案。但它仍然回溯太多。有什么解决办法吗?

添加(回答一个已删除的问题):
不幸的是我没有样本数据,谁让我这样做说他也没有样本数据,这仍然需要“到昨天”完成。如果你给我一些尽可能高效地处理这个文本的东西,我确信我可以使用它并且隐蔽,如果需要针对这项工作的特定内容。否则我会再在这里问。

4

2 回答 2

1

尽管这个问题令人困惑,但听起来您有两个不同的任务,最好使用两个不同的正则表达式来完成。这是一个经过测试的脚本,可以执行您想要的(我猜):

<?php // test.php 20110430_1100
    // Test data.
    $text = 'Foi visto que a batalha em 1939 foi. Claro'.
        ' que a data que digo ser em 1939 é uma farsa. E'.
        'm 1938 já (insert em 1910) não havia reis.';

    // Part 1: Find all numbers after "em".
    $re1 = '/\bem\b\s*(\d+)\b/i';
    $count = preg_match_all($re1, $text, $matches);
    if ($count) $numbers = $matches[1]; // Array of number strings.
    else        $numbers = array();     // Else no numbers found.

    // Part 2: Split text into sentences.
    $re2 = '/(?<=[.!?])\s+/';
    $sentences = preg_split($re2, $text, -1, PREG_SPLIT_NO_EMPTY);

    // Print out results.
    $ncnt = count($numbers); // Count of numbers found.
    printf("There were %d numbers following \"em\".\n", $ncnt);
    for ($i = 0; $i < $ncnt; ++$i) {
        printf("  Number[%d] = %s\n", $i + 1, $numbers[$i]);
    }
    $scnt = count($sentences); // Count of sentences found.
    printf("\nThere were %d sentences found.\n", $scnt);
    for ($i = 0; $i < $scnt; ++$i) {
        printf("  Sentence[%d] = \"%s\"\n", $i + 1, $sentences[$i]);
    }
?>

这是脚本的输出。

There were 4 numbers following "em".
Number[1] = 1939
Number[2] = 1939
Number[3] = 1938
Number[4] = 1910

There were 3 sentences found.
Sentence[1] = "Foi visto que a batalha em 1939 foi."
Sentence[2] = "Claro que a data que digo ser em 1939 é uma farsa."
Sentence[3] = "Em 1938 já (insert em 1910) não havia reis."

于 2011-04-30T17:20:26.733 回答
0

我不会回答关于性能的问题,但是:

  • 你不应该使用'...'来匹配......但是'......'(否则,你匹配任何3个字符的序列)。请注意,这可能会大大提高您的性能。
  • 我不会说那种语言(西班牙语),但我认为您只想匹配“em”这个词,而不是终止符(例如,balahem 1930 会匹配)。
  • 你不应该假设你在'em'和你的号码之间只有一个空格:Em__1950(用空格替换_)不匹配

编辑:关于性能:匹配重复块内的任何内容(。)会强制引擎来回运行一段时间:如果您可以匹配显式模式,它总是会快得多。

于 2011-04-30T08:12:44.140 回答