字符串的特殊preg_match

时间:2018-03-14 09:42:28

标签: php regex string preg-match

这是我的字符串:

================================================================================
                                       INPUT FILE
================================================================================
NAME = CO-c0m1.txt
|  1> ! HF def2-TZVP opt numfreq

|  2> 

|  3> % scf

|  4>      convergence tight

|  5> end

|  6> 

|  7> * xyz 0 1

|  8> C 0 0 0

|  9> O 0 0 1

| 10> *

| 11> 
| 12>                          ****END OF INPUT****
================================================================================

我想得到这个输出:

! HF def2-TZVP opt numfreq
% scf
     convergence tight
end

* xyz 0 1
C 0 0 0
O 0 0 1
*

我一直在尝试做5个小时而且做不到,请帮助,这是我的pregmatch:

$regx = '/INPUT FILE...................................................................................(.*?)........................END OF INPUT/s';
      if(preg_match($regx, $source[$i], $matches)) {
        $input[$i] = preg_replace('/\s\s\s\s+/', "\n", $matches[1]);
      }

我是正则表达式的新手,似乎很难。 有人可以帮助我,提前谢谢:)!

4 个答案:

答案 0 :(得分:2)

$p ="/[|]\s*\d*[>]\s(.+)/";
$t = "================================================================================
                                       INPUT FILE
================================================================================
NAME = CO-c0m1.txt
|  1> ! HF def2-TZVP opt numfreq

|  2> 

|  3> % scf

|  4>      convergence tight

|  5> end

|  6> 

|  7> * xyz 0 1

|  8> C 0 0 0

|  9> O 0 0 1

| 10> *

| 11> 
| 12>                          ****END OF INPUT****
================================================================================";


preg_match_all($p,$t,$res);

die(json_encode($res[1], JSON_PRETTY_PRINT));

/* Output:
[
    "! HF def2-TZVP opt numfreq",
    "% scf",
    "     convergence tight",
    "end",
    "* xyz 0 1",
    "C 0 0 0",
    "O 0 0 1",
    "*",
    "                         ****END OF INPUT****"
]
 */

$res的第二项是一个拥有你想要的数组。

答案 1 :(得分:2)

你需要一个正则表达式,它匹配以|开头的行后跟一些空格,然后是一个或多个数字,然后>,你只需要跟在这个前缀之后的文本。

正则表达式为:/^\|\s*\d+>(.*)$/m。它包含您需要的文本的捕获组。 preg_match_all()将捕获片段放入$matches[1]

preg_match_all('/^\|\s*\d+>(.*)$/m', $source[$i], $matches);
echo(implode("\n", $matches[1]));

然后,您可以通过其他方式(array_pop()array_filter()等删除包含****END OF INPUT****的行。)

检查它的实际效果:https://3v4l.org/hUEBk

regex解释说:

/             # regex delimiter
    ^         # match the beginning of the line
    \|        # match '|' (it needs to be escaped because it is a meta-character)
    \s        # match a whitespace character (space, tab)
    *         # the previous (a whitespace) can appear zero or more times
    \d        # match a digit (0..9)
    +         # the previous (a digit) can appear one or more times
    >         # match '>'
    (         # begin of a capturing group
      .*      # match any character, any number of times
    )         # end of the capturing group
    $         # match the end of the line
/             # regex delimiter
m             # multiline (regex modifier); check the regex against each line of the input string

详细了解Perl-Compatible Regular Expressions in PHP

答案 2 :(得分:1)

您不需要在文本上运行第一个正则表达式,只运行此正则表达式:

preg_match_all("/[|]\s*\d*[>]\s(.+)/", $source[$i], $matches);
echo(implode("\n", $matches[1]));

这在我的测试中运行良好。

答案 3 :(得分:1)

您可以使用单一的正则表达式解决方案一次性获取所有这些数据:

TypeHolder

故障:

  • public static string Truncate(this string s, int length) { return string.IsNullOrEmpty(s) || s.Length <= length ? s : length <= 0 ? string.Empty : s.Substring(0, length); } 匹配行的开头
  • ^\|\h+\d+>(?!\h*\Q****END OF INPUT****\E)\h\K.+ 匹配^
  • \|\h+\d+>开始否定前瞻
    • digit>如果存在horizental空白
    • (?!输入结束
    • 结束
  • \h*前瞻结束
  • \Q****END OF INPUT****\E匹配一个horizental空格然后重置匹配
  • )匹配到行尾

PHP代码:

\h\K

Live demo

.+的输出:

preg_match_all("~^\|\h+\d+>(?!\h*\Q****END OF INPUT****\E)\h\K.+~mi", $str, $matches);

您需要print_r($matches[0]);一起加入值。