我正在为python中的帐户存储工具编写一个命令解析器,并且基本功能很好。
用户在程序解释器(不是命令行参数)中输入命令,如[+] -u peter -e myemail@email.com -p password
我的问题出现在上面命令的一个用例中,我一直在“ - ”上拼写字符串以获得类似['u peter', 'e myemail@email.com', 'p password']
的列表,但如果用户的用户名中有“ - ”,该怎么办? ,这样的电子邮件或密码-p pass-word
我最终会以['u peter', 'e myemail@email.com', 'p pass', 'word']
我一直在调查正则表达式以分割命令但却无法确定它。到目前为止,我已经得到了这个\-[a-z][^\-]*
,但它也将“pass-word”样式参数分开。
有没有人知道正确或聪明的方式来做到这一点,因为在这个阶段我抓着吸管。
谢谢, 彼得
*编辑*
因此,对于最符合我需求的解决方案,我遵循了@ samkhan13的回答并放弃了正则表达式,这要归功于你们许多人给出的建议。这是我的解决方案,只要用户确实有一个被密码中的空格包围的命令,就可以使用我的用例,如果他们这样做,他们就可以使用更好的软件了!
def parseString(userInput):
poslist = [userInput.find(' -u '),
userInput.find(' -e '),
userInput.find(' -p '),
userInput.find(' -s '),
userInput.find(' -g ')]
poslist.sort()
poslist = filter(lambda a: a != -1, poslist)
text = []
for j in range(poslist.__len__()-1):
text.append(userInput[poslist[j]+2:poslist[j+1]])
text.append(userInput[poslist[poslist.__len__()-1]+2:])
return text
输入>> ' -e myemail@email.com -p pa"-ussword'
输出>> ['e myemail@email.com ', 'p pa"-ussword']
*编辑*
并且是一个处理未知命令的正则表达式
def parseString(userInput):
poslist = []
text = []
p = re.compile("\s-[a-z]\s") #searches for unix style commands
for m in p.finditer(userInput):
poslist.append(m.start())
for j in range(poslist.__len__()-1):
text.append(userInput[poslist[j]+2:poslist[j+1]])
text.append(userInput[poslist[poslist.__len__()-1]+2:])
return text
输入>> ' -e myemail@email.com -p pa"-ussword -x pmck'
输出>> ['e myemail@email.com', 'p pa"-ussword', 'x pmck']
答案 0 :(得分:0)
这种密码模式怎么样:((^|\s)-p\s)[^\s$]+
?它适用于pass-word
答案 1 :(得分:0)
此模式
-[^ ].*?(?:'.*?'|".*?")?(?:(?= -\S)|$)
即使参数符合此模式,即使密码中有-
,也会匹配参数:-p "bar -u foo"
。
它能解决你的问题吗?
警告强>
正如@shenshin指出的那样,-p "a "" - b"
不匹配。很多奇怪的案例都不会在这里被抓住,快速正则表达式的答案可能是一个“quickfix”,但对于更强大和更安全的解决方案,你可能不得不转向另一个工具。
答案 2 :(得分:0)
如果您的用例是特定的,您可以一起避免正则表达式。
def parseString(userInput):
namePosition = userInput.find('-u')
emailPosition = userInput.find('-e')
passwordPosition = userInput.find('-p')
if namePosition != -1 and emailPosition != -1 and passwordPosition != -1:
nameText = userInput[namePosition+1:emailPosition] # will look like 'u peter'
emailText = userInput[emailPosition+1:passwordPosition]
passwordText = userInput[passwordPosition+1:]
return [nameText,emailText,passwordText]
else:
print 'improper number or type of parameters given as input'
someText = '-u peter -e myemail@email.com -p password'
parsedText = parseString(someText)
print parsedText
如果您怀疑应允许用户使用-u
,-e
,-p
或其他-x
输入各种文本,请尝试修改上述示例}
答案 3 :(得分:0)
这可能比你要求的要多得多。
它并不复杂。每个部分都是一样的 唯一的区别是命令字母u,e,p。
表达式仅匹配其中的命令,因此其他表达式可以混合但不匹配
命令可以是任何顺序,甚至根本不存在。
每个命令都被严格删除,因此它们的值中可以有连字符/空格
仅捕获值,修剪前导/尾随空白。
<强>编辑强>
要添加更多命令,只需将段复制到底部并更改命令字母即可。假设所有小写字母a-z都是命令,并且必须采用严格的形式才能被视为命令。否则它的部分价值。
多数民众赞成,我在Perl中测试过,就像一个魅力。如果您想查看该测试用例,请告诉我。
# ^(?=.*(?:^\s*|\s-)u\s+((?:[^\s-]+|(?!\s*-[a-z]\s|\s*$)[\s-]+)*))?(?=.*(?:^\s*|\s-)e\s+((?:[^\s-]+|(?!\s*-[a-z]\s|\s*$)[\s-]+)*))?(?=.*(?:^\s*|\s-)p\s+((?:[^\s-]+|(?!\s*-[a-z]\s|\s*$)[\s-]+)*))?
^
(?=
.*
(?: ^ \s* | \s - )
u \s+
( # (1)
(?:
[^\s-]+
| (?! \s* - [a-z] \s | \s* $ )
[\s-]+
)*
)
)?
(?=
.*
(?: ^ \s* | \s - )
e \s+
( # (2)
(?:
[^\s-]+
| (?! \s* - [a-z] \s | \s* $ )
[\s-]+
)*
)
)?
(?=
.*
(?: ^ \s* | \s - )
p \s+
( # (3)
(?:
[^\s-]+
| (?! \s* - [a-z] \s | \s* $ )
[\s-]+
)*
)
)?
<强> EDIT2 强>
这是Perl中的测试用例
如果需要,您可以命名捕获组。在样本中,它们被编号
示例:
(?=
.*
(?: ^ \s* | \s - )
p \s+
(?P<password>
(?:
[^\s-]+
| (?! \s* - [a-z] \s | \s* $ )
[\s-]+
)*
)
)?
测试用例
$/ = undef;
my $str = <DATA>;
if ( $str =~ /^(?=.*(?:^\s*|\s-)u\s+((?:[^\s-]+|(?!\s*-[a-z]\s|\s*$)[\s-]+)*))?(?=.*(?:^\s*|\s-)e\s+((?:[^\s-]+|(?!\s*-[a-z]\s|\s*$)[\s-]+)*))?(?=.*(?:^\s*|\s-)p\s+((?:[^\s-]+|(?!\s*-[a-z]\s|\s*$)[\s-]+)*))?/s)
{
print "user = '$1'\n";
print "email = '$2'\n";
print "password = '$3'\n";
}
__DATA__
This string has commands -x, -e, -y, -p, -u commands it it
-x XVA-LUE -e asdf-myemail@-email.com -y YVA-LUE -p pa'-#@-p,s"sword -z ZVA-LUE -u Pe-ter
输出&gt;&gt;
user = 'Pe-ter'
email = 'asdf-myemail@-email.com'
password = 'pa'-#@-p,s"sword'