Regexp跨多行提取数据

时间:2018-02-28 01:17:43

标签: php regex

我需要捕获每个案例定义,然后捕获相关的php文件名。我已成功将此表达式用于单行项目

l, err := ldap.DialTLS("tcp", ldapHost, conf)
if err != nil {
    log.Fatal(err)
}
defer l.Close()

searchRequest := ldap.NewSearchRequest(
    baseDN, // The base dn to search
    ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
    "(objectClass=*)",      // The filter to apply
    []string{"contextCSN"}, // A list attributes to retrieve
    nil,
)

sr, err := l.Search(searchRequest)
if err != nil {
    log.Fatal(err)
}

for _, entry := range sr.Entries {
    for _, csn := range entry.GetAttributeValues("contextCSN") {
        ...
    }
}

我正在使用的字符串是:

$re = 'case [\"|\'](.*?)[\"|\'].*=[\s|\"|\'](.*?\.php)';

未捕获course_leaders_report和course_listing(来自regexp101.com)。

 //--- the following 2 lines are captured
 case 'course_leaders'           : $page='admin/p-members/email-leaders.php'; break;
 case 'courseDifferences'        : $page='admin/p-events/diff.php'; break;

 //--- the following two cases are not processed/captured
 case 'course_leaders_report'    :
             wp_enqueue_script( 'crsLeaders'
                               , plugin_dir_url(__FILE__).'admin/js/jquery.tablesorter.min.js'
                               , array('jquery') );
             $page='admin/p-events/leaders-report.php';
             break;
 case 'course_listing'           :
             wp_enqueue_script('courseListingDataTables' //--- name
                 //--- location of js file relative to this file
                , plugin_dir_url(__FILE__).'admin/js/DataTables/datatables.min.js'
                , array('jquery') //--- use jquery
             );
             wp_enqueue_script( 'jquery' );
             $page='admin/p-events/list-report.php';
             break;

 //--- this is being captured
 case 'course_program' : $page='admin/p-program/courseProgram.php'; break;

2 个答案:

答案 0 :(得分:3)

在PHP中,通配符.不包含换行符。所以,自己包括它们:

case [\"|\'](.*?)[\"|\'](.|\n)+?=[\s|\"|\'](.*?\.php)

注意中间的变化:.*(.|\n)+?,使量词变得懒惰。

Regex demo

或者@TimBiegeleisen在评论中指出,您可以添加标记sdot all模式运行正则表达式:

/case [\"|\'](.*?)[\"|\'].+?=[\s|\"|\'](.*?\.php)/gs

请注意,您仍然需要将?添加到量词,以使其变得懒惰。

Demo

答案 1 :(得分:0)

模式:~case ["'](\w+)["']\s*:.*?\$page=["']([\w/-]*\.php)~s

Pattern Demo

模式细分:

~                #pattern delimiter
case ["']        #match "case", a space, then a single or double quote
(\w+)            #capture group #1: greedily match one or more characters in range: A-Za-z0-9_
["']             #match single or double quote
\s*              #greedily match zero or more whitespace characters
:                #match colon
.*?              #lazily match any character (including whitespaces because of "s" pattern flag) zero or more times
\$page=["']      #match "$page=", then a single or double quote
([\w/-]*\.php)   #capture group #2: greedily match zero or more characters in range: A-Za-z0-9_/-
~                #pattern delimiter
s                #pattern modifier/flag -- makes dot also match whitespace characters

生命点:

  • [\"|\']< - 这不是定义字符类内容的方法。如果要使用字符类列出两个字符,请使用['"]。如果要使用交替,则需要使用管道,在此问题的上下文中,您需要在非捕获组中包装备选项以维护模式逻辑:(?:'|")。事实是:替代品和捕获组花费“步骤”,因此更好的语法将是一个字符类。
  • 利用发布的样本数据,捕获组可以包含非常集中的字符类。这样做,您可以使用“贪婪”匹配。贪婪匹配在步骤方面优于懒惰匹配。务必尽可能使用贪婪匹配。
  • s模式修饰符允许点(.)也匹配空白字符。这可以使用[\s\S]进行复制,但使用.修饰符的s更为简短。
  • 我不确定是否包含$page=可以提高您的实际数据的准确性,但它肯定不会受到伤害。从我的测试来看,包括$page在内的$input=<<<'INPUT' //--- the following 2 lines are captured case 'course_leaders' : \$page='admin/p-members/email-leaders.php'; break; case 'courseDifferences' : \$page='admin/p-events/diff.php'; break; //--- the following two cases are not processed/captured case 'course_leaders_report' : wp_enqueue_script( 'crsLeaders' , plugin_dir_url(__FILE__).'admin/js/jquery.tablesorter.min.js' , array('jquery') ); $page='admin/p-events/leaders-report.php'; break; case 'course_listing' : wp_enqueue_script('courseListingDataTables' //--- name //--- location of js file relative to this file , plugin_dir_url(__FILE__).'admin/js/DataTables/datatables.min.js' , array('jquery') //--- use jquery ); wp_enqueue_script( 'jquery' ); $page='admin/p-events/list-report.php'; break; //--- this is being captured case 'course_program' : $page='admin/p-program/courseProgram.php'; break; INPUT; $regex=<<<'REGEX' ~case ["'](\w+)["']\s*:.*?\$page=["']([\w/-]*\.php)~s REGEX; if (preg_match_all($regex, $input, $out)) { var_export($out); }else{ echo 'fail'; } 实际上提高了效率,因为它之前存在惰性点匹配。
  • 我在我的变量声明中使用NOWDOC语法,这样我就不必转义任何引号,也不采取任何措施来阻止在字符串中解析。

代码:(Demo

array (
  0 => 
  array (
    0 => 'case \'course_leaders\'           : \\$page=\'admin/p-members/email-leaders.php',
    1 => 'case \'courseDifferences\'        : \\$page=\'admin/p-events/diff.php',
    2 => 'case \'course_leaders_report\'    :
             wp_enqueue_script( \'crsLeaders\'
                               , plugin_dir_url(__FILE__).\'admin/js/jquery.tablesorter.min.js\'
                               , array(\'jquery\') );
             $page=\'admin/p-events/leaders-report.php',
    3 => 'case \'course_listing\'           :
             wp_enqueue_script(\'courseListingDataTables\' //--- name
                 //--- location of js file relative to this file
                , plugin_dir_url(__FILE__).\'admin/js/DataTables/datatables.min.js\'
                , array(\'jquery\') //--- use jquery
             );
             wp_enqueue_script( \'jquery\' );
             $page=\'admin/p-events/list-report.php',
    4 => 'case \'course_program\' : $page=\'admin/p-program/courseProgram.php',
  ),
  1 => 
  array (
    0 => 'course_leaders',
    1 => 'courseDifferences',
    2 => 'course_leaders_report',
    3 => 'course_listing',
    4 => 'course_program',
  ),
  2 => 
  array (
    0 => 'admin/p-members/email-leaders.php',
    1 => 'admin/p-events/diff.php',
    2 => 'admin/p-events/leaders-report.php',
    3 => 'admin/p-events/list-report.php',
    4 => 'admin/p-program/courseProgram.php',
  ),
)

输出:

CLICK....
IF | ${!LastCommandOK |
..do something
ENDIF