代码之家  ›  专栏  ›  技术社区  ›  Luca Filosofi

对模式使用字符串,但不将其删除

  •  0
  • Luca Filosofi  · 技术社区  · 14 年前

    我是个新手,顺便说一句,我学到了一些东西,但我仍然在倾注知识!

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

    假设我有以下字符串,如您所见,它们的格式可以彼此略有不同,但它们非常相似!

    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 );
    

    但为什么我相信这个regex不会工作!?)

    请帮帮我!

    附言:问题的标题解释得很清楚,我还想知道如何使用一个已知的字符串块来匹配另一个…

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

    ..不删除 DTSTART

    谢谢你的时间!

    当做 卢卡·菲洛索菲

    4 回复  |  直到 13 年前
        1
  •  1
  •   salathe    14 年前

    您可以使用一个相对简单的regex,如下所示。

    $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
    

    如果你感兴趣的行只会以 DTSTART DTEND 然后我们就可以更精确地匹配什么(例如 ^DT(?:START|END) 但是 [A-Z] 显然,这两个方面都涵盖了。

        2
  •  1
  •   dnagirl    14 年前

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

    例如:

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

    给出“这是一个句子”

        3
  •  1
  •   nik    14 年前

    您可以查看这个例子,其工作原理与您的问题类似。

    \ w+):(?p\d+)/',$str,$matches); /*然而,这也适用于php 5.2.2(pcre 7.0)和更高版本。 *为了向后兼容,建议使用上述表单*/ //preg_match('/(?\ w+):(?\ d+)/',$str,$matches); 打印($matches); ?gt;
    The above example will output:
    
    Array
    (
        [0] => foobar: 2008
        [name] => foobar
        [1] => foobar
        [digit] => 2008
        [2] => 2008
    )
    

    所以如果你只需要数字,你就需要打印出匹配的数字。

        4
  •  1
  •   Welbog    14 年前

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

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

    这是一个非常简单的表达。两者都匹配 (?:;.+?:) (?:;.+?$) ,其区别仅在于终止符(第一个匹配到冒号,第二个匹配到行尾)。

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