2017-01-25 7 views
2

У меня есть файл au3 (сценарий автоматического запуска), в котором есть много строк. НапримерСложная замена регулярных выражений, строки для вызова функции

;This is autoit 
$string1 = "This is a test string" & @crlf & "Wow, autoit syntax!" 
$string2 = "This string has a var. Var1=" & $var1 
$wow = random_function("Another string") & "this is getting complex" 
magic_function("var1=" & $var1 & @crlf & "other var=" & $var2) 
$multivar = "This string has 2 vars: var1=" & $var1 & " var2=" $var2" 

Это вид текста у меня есть, и я хотел бы, чтобы заменить каждую строку с вызовом функции. Например, выше сценарий станет

;This is autoit 
$string1 = get_string(1) & @crlf & get_string(2) 
$string2 = get_string(3,$var1) 
$wow = random_function(get_string(4)) & get_string(5) 
magic_function(get_string(6,$var1) & @crlf & get_string(7,$var2)) 
$multivar = get_string(8,$var1,$var2) 

ИЛИ

;This is autoit 
$string1 = get_string(1,@crlf) 
$string2 = get_string(3,$var1) 
$wow = random_function(get_string(4)) & get_string(5) 
magic_function(get_string(6,$var1,@crlf,$var2)) 
$multivar = get_string(8,$var1,$var2) 

Оба хороши для меня. Я думаю, что это сложная замена регулярных выражений или какая-то конкатенация тех, и поскольку моя способность к регулярному выражению меня очень разочаровывает, я прошу вас о помощи или некоторых идеях.

Я знаю, что в скрипте есть много связанных с кодом строк, которые не следует заменять, позвольте мне сделать эту часть. Мне просто нужна часть регулярного выражения.

Я думал об использовании php для создания сценария замены строк, потому что я чувствую себя более комфортно с ним. Я начинаю сценарий с

//This is php 
$file = "test.au3" 
$lines = file($file) 
foreach($lines as $index => $line){ 
$newLine = preg_replace(/*magic regex here*/); 
} 

поэтому замена может быть выполнена на каждой отдельной строке, так как у меня нет многострочных строк. Благодарим за помощь

ответ

0

Это не может быть сделано с помощью регулярного выражения. Однако это можно сделать с помощью регулярного анализа regex + stateful.

Основываясь на возможных случаях синтаксиса в вашем примере, я собрал скрипт, который выполняет эту работу. Я написал его в Python, так как мне более комфортно с этим языком, чем PHP, но комментарии с кодом + должны быть достаточно ясными, чтобы кто-то мог преобразовать его в PHP, если Python недоступен для этой задачи.

#!/usr/bin/env python 
import fileinput 
import re 

# Values you might want to modify 
filename = "test.au3" 
replacementFunctionName = "get_string" 
replacementForConcatenator = "," 



# Regexes to identify raw AutoIt elements 
string = r"""(?:"(?:[^"]|"(?="))*"|'(?:[^']|'(?='))*')""" # triple quotes is just Python 
macro = r"@\w+" # the prefix r makes the \ a literal (in the string, not the regex) 
variable = r"\$\w+" 
concatenator = r"\s*&\s*" 

# Regexes to identify compound AutoIt elements 
nonConcatenator = "(?:" + string + "|" + macro + "|" + variable + ")" 
capturingNonConcatenator = "(" + string + "|" + macro + "|" + variable + ")" 
zeroOrMoreConcatenatedNonConcatenators = "(?:" + concatenator + nonConcatenator + ")" + "*" 

# The combined search regex and its compiled form 
search = string + zeroOrMoreConcatenatedNonConcatenators 
searchRe = re.compile(search) # compiling lets us specify a start index for searches 



# Process file in place 
count = 0 # used to correctly number AutoIt string literal instances 
for line in fileinput.input(filename, inplace=True): 
    newLine = "" 

    # Convert old line to new line 
    indexInLine = 0 
    matchOfSearchRe = searchRe.search(line, indexInLine) 
    while matchOfSearchRe is not None: 
     matchReplacement = "" 

     # Replace each AutoIt string in matched substring with number 
     # and replace each concatenator with a comma 
     elementsOfMatch = re.split(capturingNonConcatenator, matchOfSearchRe.group(0)) 
     for elem in elementsOfMatch: 
      if re.match(string, elem): 
       count += 1 
       matchReplacement += str(count) 
      elif re.match(concatenator, elem): 
       matchReplacement += replacementForConcatenator 
      else: 
       matchReplacement += elem 

     # Place modified contents of match in a replacement function call 
     matchReplacement = replacementFunctionName + "(" + matchReplacement + ")" 

     # Append most recently skipped region before match and replacement for match 
     newLine += line[indexInLine:matchOfSearchRe.start()] 
     newLine += matchReplacement 

     # Update loop control variables 
     indexInLine = matchOfSearchRe.end() 
     matchOfSearchRe = searchRe.search(line, indexInLine) 

    # Append rest of line after final match 
    newLine += line[indexInLine:] 

    # Replace old line in filename with new line in place 
    print(newLine.rstrip()) 

На беглый тест, этот сценарий конвертированы

;This is autoit 
$string1 = "This is a test string" & @crlf & "Wow, autoit syntax!" 
$string2 = "This string has a var. Var1=" & $var1 
$wow = random_function("Another string") & "this is getting complex" 
magic_function("var1=" & $var1 & @crlf & "other var=" & $var2) 
$multivar = "This string has 2 vars: var1=" & $var1 & " var2=" & $var2 

в

;This is autoit 
$string1 = get_string(1,@crlf,2) 
$string2 = get_string(3,$var1) 
$wow = random_function(get_string(4)) & get_string(5) 
magic_function(get_string(6,$var1,@crlf,7,$var2)) 
$multivar = get_string(8,$var1,9,$var2) 

Если возможные случаи синтаксиса более разнообразны, чем то, что находится в вашем примере, то этот сценарий не гарантированно работает. Однако он может быть изменен в соответствии с вашими потребностями просто путем добавления или изменения «регулярных выражений для идентификации исходных элементов AutoIt» и связанных с ними «регулярных выражений для идентификации составных элементов AutoIt». Любые изменения будут собраны в переменной search, так что ничего другого не нужно будет менять в основной части сценария.

Обратите внимание, что я изменил ваш пример ввода в своем тестовом примере. Похоже, что ваш пример имел две синтаксические ошибки на последней строке: отсутствующий & и дополнительный ".

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

  • Нет связанных вопросов^_^