2017-01-25 1 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를 사용하여 replace-strings 스크립트를 작성하는 것에 대해 생각했습니다.

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

으로 스크립트를 시작하므로 여러 줄 문자열이 없기 때문에 모든 단일 줄에서 대체 할 수 있습니다. 도움을 주셔서 감사합니다.

답변

0

정규식으로는이 작업을 수행 할 수 없습니다. 그러나 regex + stateful 구문 분석을 사용하여 수행 할 수 있습니다.

예를 들어 가능한 구문 사례를 기반으로 작업을 수행하는 스크립트를 작성했습니다. 나는 파이썬으로 작성했는데, PHP보다 언어에 더 익숙해졌지만, 파이썬이이 태스크를 위해 사용할 수 없다면 코드 + 주석은 누군가를 PHP로 변환 할만큼 명확해야한다.

#!/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 = 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) 

가능한 구문의 경우이 예에있는 것보다 더 많은 다양한 경우에

;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 

변환,이 스크립트는 아니다 일하도록 보장. 그러나 "원본 AutoIt 요소를 식별하는 정규식"과 관련 "복합 AutoIt 요소를 식별하는 정규식"을 추가하거나 변경하여 필요에 맞게 수정할 수 있습니다. 모든 수정 사항은 search 변수에 수집되므로 스크립트 본문에서 다른 것을 변경할 필요가 없습니다.

필자는 테스트 케이스에서 예제 입력을 수정했습니다. 예에서 마지막 줄에 두 개의 구문 오류가있는 것으로 보입니다. 예를 들어 &이 누락되어 있고 "이 추가되었습니다.