在php中的preg_split中保留分隔符

时间:2016-02-02 17:19:20

标签: php regex preg-split

我正在尝试根据特定的分隔符将文本文件拆分为多个部分。

文本文件的片段

    1_1_ABA-BUL
Sat           Tjedan(i)   Datum            Učiona     Predavač(i)        Kolegij             Način   Grupa
Ponedjeljak
08:00-10:00   1 - 17      5.10    - 25.1   DV 12      ŠTAMPALIJA ALKA    POSLOVNI NJEMAČKI   P       1_1_ABA-BUL, 1_2_BULJ-GAB, 1_3_GAC-JUK,
                                                                         JEZIK I                     1_4_JUL-LOR, 1_5_LOS-MOR
10:00-12:00   1 - 17      5.10    - 25.1   SPORTSKA   HERCEG ROMINA      TJELESNA I          S       1_1_2_BES-BUL
                                                                         ZDRAVSTVENA
                                                                         KULTURA I
12:00-14:00   1 - 17      5.10    - 25.1   DV 26      VARGA MLADEN       INFORMATIKA         P       1_1_ABA-BUL
Utorak
08:00-10:00   1 - 17      6.10    - 26.1   DV 12      ŠTAMPALIJA ALKA    POSLOVNI NJEMAČKI   S       1_1_ABA-BUL, 1_2_BULJ-GAB, 1_3_GAC-JUK,
                                                                         JEZIK I                     1_4_JUL-LOR, 1_5_LOS-MOR
08:00-10:00   1 - 17      6.10    - 26.1   DV 20      SLADOLJEV AGEJEV   POSLOVNI ENGLESKI   P       1_1_ABA-BUL
                                                      TAMARA             JEZIK I
12:00-14:00   1 - 17      6.10    - 26.1   DV 40      ZOROJA JOVANA      INFORMATIKA         S       1_1_1_ABA-BER
12:00-14:00   1 - 17      6.10    - 26.1   DV 18      SLADOLJEV AGEJEV   POSLOVNI ENGLESKI   S       1_1_2_BES-BUL
                                                      TAMARA             JEZIK I
Srijeda
08:00-11:00   1 - 17      7.10    - 27.1   DV 01      PULJIĆ KRUNOSLAV   MATEMATIKA          P       1_1_ABA-BUL
11:00-14:00   1 - 17      7.10    - 27.1   DV 01      KRPAN MIRA         OSNOVE EKONOMIJE    P       1_1_ABA-BUL
14:00-16:00   1 - 17      7.10    - 27.1   DV 11      SLADOLJEV AGEJEV   POSLOVNI ENGLESKI   S       1_1_1_ABA-BER
                                                      TAMARA             JEZIK I
Četvrtak
11:00-14:00   1 - 17      8.10    - 28.1   DV 04      SLIŠKOVIĆ MARINA   MATEMATIKA          S       1_1_1_ABA-BER
Petak
09:00-12:00   1 - 17      9.10    - 29.1   DV 20      KRPAN MIRA         OSNOVE EKONOMIJE    S       1_1_2_BES-BUL
10:00-12:00   1 - 17      9.10    - 29.1   SPORTSKA   HERCEG ROMINA      TJELESNA I          S       1_1_1_ABA-BER
ZDRAVSTVENA
KULTURA I

12:00-15:00   1 - 17   9.10   - 29.1   DV 09   KRPAN MIRA         OSNOVE EKONOMIJE   S   1_1_1_ABA-BER
13:00-16:00   1 - 17   9.10   - 29.1   DV 01   SLIŠKOVIĆ MARINA   MATEMATIKA         S   1_1_2_BES-BUL
16:00-18:00   1 - 17   9.10   - 29.1   DV 40   AVDIĆ AMMAR,       INFORMATIKA        S   1_1_2_BES-BUL
VANJSKI INF

1_2_BULJ-GAB
Sat            Tjedan(i)   Datum            Učiona     Predavač(i)          Kolegij             Način   Grupa
Ponedjeljak
08:00-10:00    1 - 17      5.10    - 25.1   DV 12      ŠTAMPALIJA ALKA      POSLOVNI NJEMAČKI   P       1_1_ABA-BUL, 1_2_BULJ-GAB, 1_3_GAC-JUK,
                                                                            JEZIK I                     1_4_JUL-LOR, 1_5_LOS-MOR
10:00-13:00    1 - 17      5.10    - 25.1   DV 16      ŠEGO BOŠKO           MATEMATIKA          P       1_2_BULJ-GAB
14:00-16:00    1 - 17      5.10    - 25.1   DV 17      LEKAJ LUBINA BORKA   POSLOVNI ENGLESKI   P       1_2_BULJ-GAB
                                                                            JEZIK I
Utorak
08:00-10:00    1 - 17      6.10    - 26.1   DV 12      ŠTAMPALIJA ALKA      POSLOVNI NJEMAČKI   S       1_1_ABA-BUL, 1_2_BULJ-GAB, 1_3_GAC-JUK,
                                                                            JEZIK I                     1_4_JUL-LOR, 1_5_LOS-MOR
10:00-12:00    1 - 17      6.10    - 26.1   DV 01      PEJIĆ BACH MIRJANA   INFORMATIKA         P       1_2_BULJ-GAB
15:00-18:00    1 - 17      6.10    - 26.1   DV 11      HERCEG TOMISLAV      OSNOVE EKONOMIJE    P       1_2_BULJ-GAB
Srijeda
08:00-10:00    1 - 17      7.10    - 27.1   DV 42      MILANOVIĆ GLAVAN     INFORMATIKA         S       1_2_1_BULJ-DAJ
LJUBICA
10:00-12:00    1 - 17      7.10    - 27.1   DV 42      MILANOVIĆ GLAVAN     INFORMATIKA         S       1_2_2_DAK-GAB
                                                       LJUBICA
10:00-12:00    1 - 17      7.10    - 27.1   SPORTSKA   HERCEG ROMINA        TJELESNA I          S       1_2_1_BULJ-DAJ
                                                                            ZDRAVSTVENA
                                                                            KULTURA I
15:00-18:00    1 - 17      7.10    - 27.1   DV 23      HERCEG TOMISLAV      OSNOVE EKONOMIJE    S       1_2_1_BULJ-DAJ
18:00-21:00    1 - 17      7.10    - 27.1   DV 23      HERCEG TOMISLAV      OSNOVE EKONOMIJE    S       1_2_2_DAK-GAB
Četvrtak
Petak
10:00-12:00    1 - 17      9.10    - 29.1   SPORTSKA   HERCEG ROMINA        TJELESNA I          S       1_2_2_DAK-GAB
                                                                            ZDRAVSTVENA
                                                                            KULTURA I
11:00-14:00    1 - 17      9.10    - 29.1   DV 19      ŠKRINJARIĆ TIHANA    MATEMATIKA          S       1_2_1_BULJ-DAJ

12:00-14:00   1 - 17   9.10   - 29.1   DV 16   LEKAJ LUBINA BORKA   POSLOVNI ENGLESKI   S   1_2_2_DAK-GAB
                                                                    JEZIK I
14:00-17:00   1 - 17   9.10   - 29.1   DV 02   ŠKRINJARIĆ TIHANA    MATEMATIKA          S   1_2_2_DAK-GAB
14:00-16:00   1 - 17   9.10   - 29.1   DV 10   LEKAJ LUBINA BORKA   POSLOVNI ENGLESKI   S   1_2_1_BULJ-DAJ
JEZIK I

我将字符串拆分为1_1_ABA-BUL行和其他相同格式的行(在“Sat”字符串之上)。

这是我的preg_split行

$grupe = preg_split("/((.*?)\nSat)/", $source, PREG_SPLIT_NO_EMPTY |  PREG_SPLIT_DELIM_CAPTURE);

以下preg_split行不保留分隔符(1_1_ABA-BUL等)。如果我将其更改为

  $grupe = preg_split("/((.*?)\nSat)/", $source, -1, PREG_SPLIT_NO_EMPTY |  PREG_SPLIT_DELIM_CAPTURE);

结果数组不正确(我得到了损坏的结果)。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

您使用preg_split()的第一种方式似乎有效,但事实上并非如此。

它的第三个参数($limit)是要返回的碎片数。碰巧你使用的文本不够长,片数小于或等于3(PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE的值)。

这就是你如何使它发挥作用:

$grupe = preg_split('/(.*?)\n(?=Sat)/', $source, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

这是print_r($grupe)

的(截断)列表
Array
(
    [0] =>     1_1_ABA-BUL
    [1] => Sat           Tjedan(i)   Datum            Učiona     Predavač(i)        Kolegij             Način   Grupa
Ponedjeljak
08:00-10:00   1 - 17      5.10    - 25.1   DV 12      ŠTAMPALIJA ALKA    POSLOVNI NJEMAČKI   P       1_1_ABA-BUL, 1_2_BULJ-GAB, 1_3_GAC-JUK,
                                                                         JEZIK I                     1_4_JUL-LOR, 1_5_LOS-MOR
...
16:00-18:00   1 - 17   9.10   - 29.1   DV 40   AVDIĆ AMMAR,       INFORMATIKA        S   1_1_2_BES-BUL
VANJSKI INF


    [2] => 1_2_BULJ-GAB
    [3] => Sat            Tjedan(i)   Datum            Učiona     Predavač(i)          Kolegij             Način   Grupa
Ponedjeljak
08:00-10:00    1 - 17      5.10    - 25.1   DV 12      ŠTAMPALIJA ALKA      POSLOVNI NJEMAČKI   P       1_1_ABA-BUL, 1_2_BULJ-GAB, 1_3_GAC-JUK,
...
14:00-16:00   1 - 17   9.10   - 29.1   DV 10   LEKAJ LUBINA BORKA   POSLOVNI ENGLESKI   S   1_2_1_BULJ-DAJ
JEZIK I

)

工作原理:

正则表达式的重要更改是assertion (?=Sat)。它表示正则表达式的前一部分((.*?)\n)仅匹配字符串的一部分,前提是该部分字符串后跟Sat。断言仅检查输入字符串中的下一个字符,但不消耗它们。 Sat部分不会成为分隔符的一部分。

其余的没有变化。标志PREG_SPLIT_DELIM_CAPTURE使preg_split()将正则表达式分隔符的捕获部分作为输出的各个部分返回。在抵消02上找到它们。 Sat子字符串,只是一个断言,不是分隔符的一部分,但它会在下一个部分(它所属的地方)中返回。