Python 如何使用正则表达式验证字符串的格式
假设我有一个字符串,看起来像:Python 如何使用正则表达式验证字符串的格式,python,regex,Python,Regex,假设我有一个字符串,看起来像: first_string = "(white cats || 'dogs) && ($1,000 || $500-$900' || 1,000+)" 我用文本“replace”替换每个单词,方法是: new_string = re.sub(r'[\w$\-+,][\w$\-+,\t ]*[\w$\-+,]|[\w$\-+,],', "replace", first_string, flags=re.IGNORECASE) 然后我出去: new_
first_string = "(white cats || 'dogs) && ($1,000 || $500-$900' || 1,000+)"
我用文本“replace”替换每个单词,方法是:
new_string = re.sub(r'[\w$\-+,][\w$\-+,\t ]*[\w$\-+,]|[\w$\-+,],', "replace", first_string, flags=re.IGNORECASE)
然后我出去:
new_string = "(replace || replace) && (replace || replace || replace)"
这个很好用。但我想验证新的_字符串是否具有特定的格式
例如,是否有一种使用正则表达式的方法来确保新的_字符串符合上述通用格式,其中:
- 总是有多组参数,由
&&
- 每个paren集包含由
| |
- 每个paren集合中的字符串数量和paren集合的数量可能不同
- 未使用正则表达式
def is_valid(s):
def surrounded_by_parens(s, next_validation):
s = s.strip()
return s.startswith('(') and s.endswith(')') and next_validation(s[1:-1])
def separated_by_bars(s):
return all(x.strip() == 'replace' for x in s.split('||'))
return all(surrounded_by_parens(x, separated_by_bars) for x in s.split('&&'))
assert is_valid("(replace || replace) && (replace || replace || replace)")
assert is_valid("(replace || replace)")
assert not is_valid("(replace replace) && (replace || replace || replace)")
assert not is_valid("(replace || replace) (replace || replace || replace)")
始终可以使正则表达式与您想要的任何一组配置或格式匹配。但是,匹配一组格式所需的一些字符串非常长。这一个还不错:
re.match(r"\( \w+ (\|\| \w+ )*\)( && \( \w+ (\|\| \w+ )*\))*$", new_string)
这将匹配:
( replace )
( replace || replace || replace )
( replace || replace ) && ( replace )
( replace || replace ) && ( replace || replace ) && ( replace || replace )
您可以使用以下模式检查字符串结构:
^(?:(?:^|\s*[&|]{2}\s*)\([^|)]+(?:\s*\|\|\s*[^|)]+)*\))*$
如果&&
也可以在括号内,则可以使用:
^(?:(?:^|\s*[&|]{2}\s*)\([^&|)]+(?:\s*[&|]{2}\s*[^&|)]+)*\))*$
如果替换模式良好,则不需要检查父对象和“子对象”是否具有相同的结构
注意:如果要允许空括号,请将所有的+
量词替换为*
说明
此正则表达式将与MT(replace | | replace)和&(replace | | replace | replace)
中描述的匹配,其中:
- 总有一组paren,由一个&&
- 每个paren集包含由分隔的字符串||
- 每个paren集合中的字符串数量和paren集合的数量可能不同
^((?:&&&&&&&&&&&^)s*(?:(?:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\)+\)\s*(?=(?:&&&&&&$)+
输入文本:
(Areplace || replace) && (replace || replace || replace)
(Breplace || replace) fda && (replace || replace || replace)
(Creplace || replace) && (replace || replace || replace) && (Creplace || replace)
(whitecats || 'dogs) && ($1,000 || $500-$900' || 1,000+)
火柴
[0] => (Areplace || replace) && (replace || replace || replace)
[1] => (Creplace || replace) && (replace || replace || replace) && (Creplace || replace)
[2] => (whitecats || 'dogs) && ($1,000 || $500-$900' || 1,000+)
当我使用regex进行验证时,我会定义字符串的一般格式,然后简单地检查我的regex是否在输入字符串上生成任何匹配项。这假设我实际上可以定义所需的正则表达式,尽管我不太确定是否可以为这些给定条件定义正则表达式。只需使用pyparsing编写一个解析器。好吧,经典的问题是——我什么都没试过——不知道这是否可能。我想我是在问应该尝试什么,并假设我需要一个regex,我对它的了解很少。还匹配
(replace | | replace)fdafd&&(replace | | replace)&&(replace | | replace)
哦,哇!已更改为修复男性的观察。未通过OP示例(替换| |替换)和&(替换| |替换| |替换)
谢谢,这看起来可以工作。一个新手的后续问题:我会使用re.match吗?好问题,我对python不太了解,但是在PHP中我使用了那块输入文本和preg\u match\u all('/^(((?:&&&&&&&&&^)s*\(?:(?:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\代码>以给出结果部分。如果您只验证一个字符串,那么re.match应该可以工作,但是您需要在正则表达式的末尾包含一个$
,以确保格式化字符串后面没有任何其他内容。谢谢,这可以工作,除非我省略了| |,然后它仍然将该字符串作为匹配项进行评估。@user1697845:好的,已更正,但是我想&&可以在括号内?谢谢,是的&&可以在括号内,我想| |也可以在它们之间