2017-01-27 3 views
1

В python я пытаюсь реализовать определяемое пользователем выражение регулярного выражения путем разбора его на пользовательское выражение регулярного выражения. это пользовательское выражение регулярного выражения затем применяется к строке, отделяемой пробелом. Идея заключается в применении пользовательского регулярного выражения на второй столбец без использования цикла for.Python, применяя regex negative lookahead recursivly

Stream //streams/sys_util mainline none 'sys_util' 
Stream //streams/gta mainline none 'gta' 
Stream //streams/gta_client development //streams/gta_cdevelop 'gta_client' 
Stream //streams/gta_develop development //streams/gta 'gta_develop' 
Stream //streams/gta_infrastructure development //streams/gta 'gta_infrastructure' 
Stream //streams/gta_server development //streams/gta_cdevelop 'gta_server' 
Stream //streams/0222_ImplAlig1.0 task none '0222_ImplAlig1.0' 
Stream //streams/0377_kzo_the_wart task //streams/applications_int '0377_tta' 

Ожидаемый результат должен быть

//streams/gta 
//streams/gta_client 
//streams/gta_develop 
//streams/gta_infrastructure 
//streams/gta_server 

вот мой код,

import re 
mystring = "..." 
match_rgx = r'Stream\s(\/\/streams\/gta.*)(?!\s)' 
result = re.findall(match_rgx, mystring, re.M) 

Примечание: Выражение внутри первой скобкой не может быть изменен (как он обрабатывается с пользователем ввод), поэтому \/\/streams\/gta.* должен оставаться таким, какой он есть.

Как я могу улучшить негативный внешний вид, чтобы получить желаемые результаты?

+0

Вы тестируете другой вход, верно? Ваш шаблон содержит 'tda_cl', который отсутствует на вашем входе. Кажется, вам нужен 'r'Stream \ s + (// streams/gta (?: _ \ W +)?) '' –

+0

Может быть, 'Stream \ s (// streams/gta. *?) (? = \ S | $) '(или' Stream \ s (// streams/gta. *?) (?! \ S) ') будет делать? Было бы лучше, если бы вы могли показать реальный, а не упрощенный код, который у вас есть. –

+0

извините, это была опечатка. match_rgx обязательно должен указывать gta. *, поскольку он исходит от пользователя.Я хочу применить определенное пользователем регулярное выражение только во второй coloumn. надеюсь это поможет. – Sha

ответ

1

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

match_rgx = 'Stream\s(//streams/gta.*?)\s' 
result = re.findall(match_rgx, mystring) 

По умолчанию оператор * жадный, поэтому он будет пытаться поймать столько текст, насколько это возможно (например: «// Струйные/Gta магистраль NONE» будет соответствовать без?). Но вам нужен только второй столбец, так что? ваш оператор становится неживым и останавливается на минимальном шаблоне, здесь, при первом вхождении \ s ("// streams/gta").

Надеюсь, что это ясно, посмотрите на документ (https://docs.python.org/2/library/re.html#contents-of-module-re), если это не так.

Btw, вам не нужно избегать /, это не особый символ. И бесполезно использовать флаг re.M, если вы не используете^или $.

Редактировать: Поскольку вы редактируете, если вы не хотите ловить разработку, некоторые сведения стали бесполезными.

Редактировать 2: Не видел, чтобы вы не хотели менять шаблон. В этом случае просто выполните:

match_rgx = 'Stream\s(\/\/streams\/gta.*?)\s' 

Редактировать3: Смотреть комментарий.

+0

Отлично, вот что я искал. не могли бы вы объяснить, что делает? после. * imply – Sha

+0

@Sha Я добавлю его к ответу. – Liad

+1

@Sha Не стесняйтесь принимать ответ, если он достаточно полезен. – Liad

0

Испытано на https://regex101.com/, это должно сделать работу для всех 2-ой колонки:

(?:\w+\s([^\s]+)\s.*[\n|\n\r]*) 

И это для ВПОН 2 только колонки:

(?:\w+\s(\/\/streams\/gta[^\s]*)\s.*[\n|\n\r]*) 

Для одной линии было бы так же, как (второй столбец):

\w+\s([^\s]+)\s.* 

Gta только на 1 линии:

\w+\s(\/\/streams\/gta[^\s]*)\s.* 
+0

К сожалению, '\/\/streams \ /gta.*' не может быть изменен, так как это будет пользовательский ввод. Идея заключается в применении пользовательских выражений регулярного выражения во втором столбце. – Sha

+0

Если вы берете '\ w + \ s (\/\/streams \/gta [^ \ s] *) \ s. *' (4-й пример) и изменяете строку потока для ввода пользователем, она будет работать: '\ w + \ s ( [^ \ s] *) \ s. * 'Если есть какие-то проблемы, я не вижу этого, не могли бы вы быть более явными? – Tatranskymedved

+0

Пользовательский ввод ** \/\/streams \/gta. *** Потому что. * Включает все, что делает [^ \ s] *) \ s. * Становится неэффективным. – Sha

Смежные вопросы