mirror of
https://github.com/tickstep/aliyunpan.git
synced 2025-01-23 14:32:14 +08:00
98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
// Copyright (c) 2020 tickstep.
|
||
//
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
package args
|
||
|
||
import (
|
||
"strings"
|
||
"unicode"
|
||
)
|
||
|
||
const (
|
||
CharEscape = '\\'
|
||
CharSingleQuote = '\''
|
||
CharDoubleQuote = '"'
|
||
CharBackQuote = '`'
|
||
)
|
||
|
||
// IsQuote 是否为引号
|
||
func IsQuote(r rune) bool {
|
||
return r == CharSingleQuote || r == CharDoubleQuote || r == CharBackQuote
|
||
}
|
||
|
||
// Parse 解析line, 忽略括号
|
||
func Parse(line string) (lineArgs []string) { // 在函数中定义的返回值变量,会自动赋为 zero-value,即相当于 var lineArgs string[]
|
||
var (
|
||
rl = []rune(line + " ")
|
||
buf = strings.Builder{}
|
||
quoteChar rune
|
||
nextChar rune
|
||
escaped bool
|
||
in bool
|
||
)
|
||
|
||
var (
|
||
isSpace bool
|
||
)
|
||
|
||
for k, r := range rl {
|
||
isSpace = unicode.IsSpace(r)
|
||
if !isSpace && !in {
|
||
in = true
|
||
}
|
||
|
||
switch {
|
||
case escaped: // 已转义, 跳过
|
||
escaped = false
|
||
//pass
|
||
case r == CharEscape: // 转义模式
|
||
if k+1+1 < len(rl) { // 不是最后一个字符, 多+1是因为最后一个空格
|
||
nextChar = rl[k+1]
|
||
// 仅支持转义这些字符, 否则原样输出反斜杠
|
||
if unicode.IsSpace(nextChar) || IsQuote(nextChar) || nextChar == CharEscape {
|
||
escaped = true
|
||
continue
|
||
}
|
||
}
|
||
// pass
|
||
case IsQuote(r):
|
||
if quoteChar == 0 { //未引
|
||
quoteChar = r
|
||
continue
|
||
}
|
||
|
||
if quoteChar == r { //取消引
|
||
quoteChar = 0
|
||
continue
|
||
}
|
||
case isSpace:
|
||
if !in { // 忽略多余的空格
|
||
continue
|
||
}
|
||
if quoteChar == 0 { // 未在引号内
|
||
lineArgs = append(lineArgs, buf.String())
|
||
buf.Reset()
|
||
in = false
|
||
continue
|
||
}
|
||
}
|
||
|
||
buf.WriteRune(r)
|
||
}
|
||
|
||
// Go 允许在定义函数时,命名返回值,当然这些变量可以在函数中使用。
|
||
// 在 return 语句中,无需显示的返回这些值,Go 会自动将其返回。当然 return 语句还是必须要写的,否则编译器会报错。
|
||
// 相当于 return lineArgs
|
||
return
|
||
}
|