2016-05-14 8 views
0

Я хотел бы анализировать инструкции определения в файле PHP с использованием регулярного выражения Python. (Или другими словами: я хочу использовать Python для разбора PHP файл.)Parsing PHP define statement с регулярным выражением Python

Что я хотел бы разобрать это определить такие заявления:

define("My_KEY", "My_Value l"); 
define('My_KEY', 'My_Value'); 
define( 'My_KEY' , "My_Value" ); 

Так что я придумал следующее Python регулярное выражение:

define\(\s*["']{1}(.[^'"]*)["']{1}\s*,\s*["']{1}(.[^'"]*)["']{1}\s*\) 

Это прекрасно работает, до тех пор, пока не использование " или ' внутри определения заявления. Например, что-то вроде этого не будет работать:

define( 'My_KEY' , 'My\'_\'Value' ); 
define( 'My_KEY' , "My'_'Value" ); 

Любые идеи, как подойти к этой проблеме?

+1

Является ли регулярное выражение необходимо для всей задачи? Вы можете использовать регулярное выражение, чтобы найти 'define (..)', затем разделите строку между parens и обрезайте ее и т. Д., Чтобы получить нужные значения. –

+0

См. Http: // stackoverflow.com/questions/1352693/how-to-match-a-quoted-string-with-escaped-quotes-in-it – Barmar

+1

@AndyG да, я мог бы, но я хочу узнать больше о том, как использовать регулярное выражение, так что почему я возник вопрос. – manuel

ответ

0

В питона,

str="define( 'My_KEY' , 'My\'_\'Value' )"; 
import re 
re.sub(r"""^define\(\s*['"]*(.*?)['"]*[\s,]+['"]*(.*?)['"]*\s*\)""",r'\2 ; \1', str) 

Выход:

"My'_'Value ; My_KEY" 
1

Вы можете использовать что-то вроде:

import re 
result = re.findall(r"""^define\(\s*['"]*(.*?)['"]*[\s,]+['"]*(.*?)['"]*\s*\)""", subject, re.IGNORECASE | re.DOTALL | re.MULTILINE) 

Regex101 Demo and Explanation


Матчи:

MATCH 1 
1. [8-14] `My_KEY` 
2. [18-28] `My_Value l` 
MATCH 2 
1. [40-46] `My_KEY` 
2. [50-58] `My_Value` 
MATCH 3 
1. [73-79] `My_KEY` 
2. [88-96] `My_Value` 
MATCH 4 
1. [114-120] `My_KEY` 
2. [129-141] `My\'_\'Value` 
MATCH 5 
1. [159-165] `My_KEY` 
2. [174-184] `My'_'Value` 
+0

это отлично выглядит. Но как это работает? почему он не останавливается, когда достигает «или»? – manuel

+0

Я не знаю, где вы упоминаете «или» в своем вопросе? –

1

Используйте взгляд обходных с этим монстром регулярным выражением:

define\(\s*(["'])(?P<key>.+?(?=\1))\1\s*, 
\s*(["'])(?P<value>.+?)(?=\3)(?<!\\)\3 

См a demo on regex101.com.

0

Описание

Это регулярное выражение будет делать следующее:

  • матча все строки, начинающиеся с define и имеют ключ и значение, установленное внутри круглых скобок
  • захвата ключа и значения строк, не включая обмоточные котировки
  • все ключи и стоимость, которые должны быть обернуты в одинарные или двойные кавычки
  • правильная ручка с экранированными кавычками
  • избежать сложных случаев края, как:
    • define('file path', "C:\\windows\\temp\\"); где сбежавший слэш может существовать до закрытия цитаты

Regex

Примечание: используя следующие флаги: случай -независимая, глобальная, многострочная

^define\(\s*(['"])((?:\\\1|(?:(?!\1).))*)\1\s*,\s*(['"])((?:\\\3|(?:(?!\3).))*)\3\s*\); 

Regular expression visualization

Захват группы

  • захвата группы 0 получает всю строку
  • группа захвата 1 получает тип цитаты, окружающий key
  • захвата группы 2 получает в key строку внутри котировки
  • группа захвата 3 получает тип цитаты, окружающий е value
  • захвата группа 4 получает value строку внутри кавычек

Примеры

Live Demo

https://regex101.com/r/oP4sV0/1

Образец текста

define("0 My_KEY", "0 My_Value l"); 
define('1 My_KEY', '1 My_Value'); 
define( '2 My_KEY' , "2 My_Value" ); 
define( '3 My_KEY\\' , '3 My\'_\'Value' ); 
define( '4 My_KEY' , "4 My'_'Value\\" ); 

Образец Матчи

[0][0] = define("0 My_KEY", "0 My_Value l"); 
[0][1] = " 
[0][2] = 0 My_KEY 
[0][3] = " 
[0][4] = 0 My_Value l 

[1][0] = define('1 My_KEY', '1 My_Value'); 
[1][1] = ' 
[1][2] = 1 My_KEY 
[1][3] = ' 
[1][4] = 1 My_Value 

[2][0] = define( '2 My_KEY' , "2 My_Value" ); 
[2][1] = ' 
[2][2] = 2 My_KEY 
[2][3] = " 
[2][4] = 2 My_Value 

[3][0] = define( '3 My_KEY' , '3 My\'_\'Value' ); 
[3][1] = ' 
[3][2] = 3 My_KEY\\ 
[3][3] = ' 
[3][4] = 3 My\'_\'Value 

[4][0] = define( '4 My_KEY' , "4 My'_'Value" ); 
[4][1] = ' 
[4][2] = 4 My_KEY 
[4][3] = " 
[4][4] = 4 My'_'Value\\ 

Объяснение

NODE      EXPLANATION 
---------------------------------------------------------------------- 
^      the beginning of a "line" 
---------------------------------------------------------------------- 
    define     'define' 
---------------------------------------------------------------------- 
    \(      '(' 
---------------------------------------------------------------------- 
    \s*      whitespace (\n, \r, \t, \f, and " ") (0 or 
          more times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    ['"]      any character of: ''', '"' 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
    (      group and capture to \2: 
---------------------------------------------------------------------- 
    (?:      group, but do not capture (0 or more 
          times (matching the most amount 
          possible)): 
---------------------------------------------------------------------- 
     \\      '\' 
---------------------------------------------------------------------- 
     \1      what was matched by capture \1 
---------------------------------------------------------------------- 
    |      OR 
---------------------------------------------------------------------- 
     (?:      group, but do not capture: 
---------------------------------------------------------------------- 
     (?!      look ahead to see if there is not: 
---------------------------------------------------------------------- 
      \1      what was matched by capture \1 
---------------------------------------------------------------------- 
     )      end of look-ahead 
---------------------------------------------------------------------- 
     .      any character except \n 
---------------------------------------------------------------------- 
    )      end of grouping 
---------------------------------------------------------------------- 
    )*      end of grouping 
---------------------------------------------------------------------- 
)      end of \2 
---------------------------------------------------------------------- 
    \1      what was matched by capture \1 
---------------------------------------------------------------------- 
    \s*      whitespace (\n, \r, \t, \f, and " ") (0 or 
          more times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
    ,      ',' 
---------------------------------------------------------------------- 
    \s*      whitespace (\n, \r, \t, \f, and " ") (0 or 
          more times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
    (      group and capture to \3: 
---------------------------------------------------------------------- 
    ['"]      any character of: ''', '"' 
---------------------------------------------------------------------- 
)      end of \3 
---------------------------------------------------------------------- 
    (      group and capture to \4: 
---------------------------------------------------------------------- 
    (?:      group, but do not capture (0 or more 
          times (matching the most amount 
          possible)): 
---------------------------------------------------------------------- 
     \\      '\' 
---------------------------------------------------------------------- 
     \3      what was matched by capture \3 
---------------------------------------------------------------------- 
    |      OR 
---------------------------------------------------------------------- 
     (?:      group, but do not capture: 
---------------------------------------------------------------------- 
     (?!      look ahead to see if there is not: 
---------------------------------------------------------------------- 
      \3      what was matched by capture \3 
---------------------------------------------------------------------- 
     )      end of look-ahead 
---------------------------------------------------------------------- 
     .      any character except \n 
---------------------------------------------------------------------- 
    )      end of grouping 
---------------------------------------------------------------------- 
    )*      end of grouping 
---------------------------------------------------------------------- 
)      end of \4 
---------------------------------------------------------------------- 
    \3      what was matched by capture \3 
---------------------------------------------------------------------- 
    \s*      whitespace (\n, \r, \t, \f, and " ") (0 or 
          more times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
    \)      ')' 
---------------------------------------------------------------------- 
    ;      ';' 
Смежные вопросы