正则表达式匹配 - 曲目

时间:2013-07-21 08:23:35

标签: php regex

我有一个看起来像

的字符串
A GOMUP 59/20 61/30 63/40 64/50 64/60 MUSVA DUTUM

我正在尝试编写与此字符串匹配的正则表达式,并返回数组中的每个空间文本。它必须确保第一个字母是1位数。

我试过的正则表达式无法实现我的预期

#^([A-Z])(?:\s(\S+))+#

返回

array(3) {
  [0]=>
  array(1) {
    [0]=>
    string(49) "A GOMUP 59/20 61/30 63/40 64/50 64/60 MUSVA DUTUM"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "A"
  }
  [2]=>
  array(1) {
    [0]=>
    string(5) "DUTUM"
  }
}

我希望/想要回归

array(10) {
  [0]=>
  array(1) {
    [0]=>
    string(49) "A GOMUP 59/20 61/30 63/40 64/50 64/60 MUSVA DUTUM"
  }
  [1]=>
  array(1) {
    [0]=>
    string(1) "A"
  }
  [2]=>
  array(1) {
    [0]=>
    string(5) "GOMUP"
  }
  [3]=>
  array(1) {
    [0]=>
    string(5) "59/20"
  }
  [4]=>
  array(1) {
    [0]=>
    string(5) "61/30"
  }
  [5]=>
  array(1) {
    [0]=>
    string(5) "63/40"
  }
  [6]=>
  array(1) {
    [0]=>
    string(5) "64/50"
  }
  [7]=>
  array(1) {
    [0]=>
    string(5) "64/60"
  }
  [8]=>
  array(1) {
    [0]=>
    string(5) "MUSVA"
  }
  [9]=>
  array(1) {
    [0]=>
    string(5) "DUTUM"
  }
}

如何实现这一目标?我在PHP中使用preg_match。

3 个答案:

答案 0 :(得分:2)

要拆分字符串并同时检查第一项是否为单个字母,您可以使用此模式:

$pattern = '~^[A-Z]\b|\G\s+\K\S+~';

$subject = 'A GOMUP 59/20 61/30 63/40 64/50 64/60 MUSVA DUTUM';

preg_match_all($pattern, $subject, $matches);

print_r($matches[0]);

您获得:

Array
(
    [0] => A
    [1] => GOMUP
    [2] => 59/20
    [3] => 61/30
    [4] => 63/40
    [5] => 64/50
    [6] => 64/60
    [7] => MUSVA
    [8] => DUTUM
)

如果我测试字符串ZZ A GOMUP 59/20 61/30 63/40 64/50 64/60 MUSVA DUTUM,则模式失败并且不返回任何结果。

但是,您可以使用此模式找到以单个字母开头的第一个子字符串:

$pattern = '~^(?>\S{2,}\s+)*\K[A-Z]\b|\G\s+\K\S+~';



Pattern1详细信息: ~^[A-Z]\b|\G\s+\K\S+~

~          # pattern delimiter
^          # begining of the string anchor
[A-Z]\b    # single uppercase letter with a word boundary
|          # OR
\G         # contiguous match from the last
\s+        # one or more white characters (spaces, tab, newlines...)
           # which can be replaced by ' +' for your example string
\K         # reset the match before (remove the spaces from the result)
\S+        # all that is not a space
~          # pattern delimiter

Pattern2详细信息: ~^(?>\S{2,}\s+)*\K[A-Z]\b|\G\s+\K\S+~

~          # pattern delimiter
^          # begining of the string anchor
(?>        # open a group (atomic here but you can use '(?:' instead)
  \S{2,}   # a non space character repeated at least two times
  \s+      # one or more spaces
)*         # repeat the group zero or more times
\K         # reset the begining of the match

之后就像是Pattern1。

答案 1 :(得分:0)

PHP中的正则表达式不允许可变数量的匹配组,因此您必须为字符串的每个部分编写一个组。参见例如http://www.regular-expressions.info/captureall.html

使用explode或preg_split将字符串拆分为空格会更容易,然后才进行额外的检查。

答案 2 :(得分:0)

if (preg_match_all('#([A-Z]+)|([\d]+/[\d]+)#', $text, $matches)){
    print_r($matches[0]);
}

输出:

Array
(
    [0] => A
    [1] => GOMUP
    [2] => 59/20
    [3] => 61/30
    [4] => 63/40
    [5] => 64/50
    [6] => 64/60
    [7] => MUSVA
    [8] => DUTUM
)