在 php 中保留 preg_split 中的分隔符

Keeping the delimiter in preg_split in php

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

文本文件的片段

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

生成的数组不正确(我得到了错误的结果)。

我做错了什么?

您使用的第一种方法 preg_split() 似乎可行,但实际上行不通。

它的第三个参数($limit)是return的棋子数。刚好你用的文不够长,条数小于等于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() return 正则表达式定界符的捕获部分作为输出的各个部分。在上面的偏移量 02 处找到它们。 Sat 子字符串只是一个断言,它不是定界符的一部分,但在下一段(它所属的位置)中被 return 编辑。