对模式使用字符串但从被删除中排除它

时间:2010-04-28 14:44:47

标签: php regex preg-replace lookahead lookbehind

我对正则表达式很新,我顺便学到了一些东西,但仍然倾注了知识!

所以我想请你澄清它是如何工作的!

假设我有以下字符串,你可以看到它们的格式可能不同,但它们非常相似!

DTSTART;TZID="America/Chicago":20030819T000000
DTEND;TZID="America/Chicago":20030819T010000
DTSTART;TZID=US/Pacific
DTSTART;VALUE=DATE

现在我想要替换 第一个A-Z区块冒号之间的所有所以例如我会保留

DTSTART:20030819T000000
DTEND:20030819T010000
DTSTART
DTSTART

所以根据我的新手知识,我已经找到了这个糟糕的正则表达式! : - (

preg_replace( '/^[A-Z](?!;[A-Z]=[\w\W]+):$/m' , '' , $data );

但为什么我确定这个正则表达式不起作用!? : - )

请帮助我!

PS:问题的标题很有说服力,我也想知道如何使用一个众所周知的字符串块来匹配另一个...

preg_replace( '/^[DTSTART](?!;[A-Z]=[\w\W]+):$/m' , '' , $data );

..不删除DTSTART

感谢您的时间!

此致 Luca Filosofi

4 个答案:

答案 0 :(得分:1)

你想要删除分号和冒号或行尾之间的所有内容,对吗?所以用它作为你的表达。你的事情太复杂了。

preg_replace('/(?:;.+?:)|(?:;.+?$)/m','',$data);

这是一个非常简单的表达方式。匹配(?:;.+?:)(?:;.+?$),它们的区别仅在于它们的终结符(第一个匹配冒号,第二个匹配到行尾)。

每个都是以分号开头的非捕获组,不情愿地读取所有字符,然后停在终结符处。根据您的描述,所有匹配的东西都可以移除。

答案 1 :(得分:1)

如果你想在替换中保留匹配模式的一部分,你可以在它周围加上括号,然后用$ 1(或者它的任何分组)来引用它。

例如:

s/^(this is a sentence) to edit/$1/

给出“这是一个句子”

答案 2 :(得分:1)

您可以查看此示例与您的问题类似的工作

   \ w +):(?P \ d +)/',$ str,$ matches);     / *这也适用于PHP 5.2.2(PCRE 7.0)及更高版本      *建议使用上述表格以便向后兼容* /     // preg_match('/(?\ w +):(?\ d +)/',$ str,$ matches);     的print_r($比赛);     ?>
The above example will output:

Array
(
    [0] => foobar: 2008
    [name] => foobar
    [1] => foobar
    [digit] => 2008
    [2] => 2008
)

所以如果你只需要数字你需要打印$ matches [digit]

答案 3 :(得分:1)

您可以使用相对简单的正则表达式,如下所示。

$subject = 'DTSTART;TZID="America/Chicago":20030819T000000
DTEND;TZID="America/Chicago":20030819T010000
DTSTART;TZID=US/Pacific
DTSTART;VALUE=DATE';

echo preg_replace('/^[A-Z]+\K[^:\n]*/m', '', $subject) . PHP_EOL;

它在一行的开头查找一系列大写字母,将匹配起点(即\K所做的)重置到那些结尾,并匹配任何不是冒号或换行符的东西(即部分)你想删除)。然后用空字符串替换那些匹配的部分。

上面的输出是

DTSTART:20030819T000000
DTEND:20030819T010000
DTSTART
DTSTART

如果您感兴趣的行只会以DTSTARTDTEND开头,那么我们可以更准确地说明要匹配的内容(例如^DT(?:START|END)),但{{1}显然涵盖了这两个。