【问题标题】:Regex to match an identifier and rejecting those containing invalid character正则表达式匹配标识符并拒绝包含无效字符的标识符
【发布时间】:2018-07-10 02:29:52
【问题描述】:

我正在定义一个正则表达式来匹配我定义的标识符 - 标识符必须以一个字母开头,后跟任意数量的字母、数字和下划线。

我有我当前的正则表达式r'[A-Za-z][A-Za-z0-9_]*',它工作得很好,除了这样的情况:如果我发送:testid@entifier_,它会返回testidentifier_ 的匹配项。我希望它完全拒绝标识符。部分不匹配。

它只是最终将它们分开。

如果不对合法字符使用复杂的前瞻,我该怎么办?

输入很简单:

arg = sys.argv[1]
file = open(arg)
inLines = file.read()
file.close()
tokens = lexer(inLines, tokenFormats)

我定义的正则表达式示例如下:

tokenFormats = [
    (r'[\s\n\t]+', None), #Whitespace
    (r'\/\*(\*(?!\/)|[^*])*\*\/', None), #Comment
    (r'\(', LParent),
    (r'\)', RParent),
    (r'\[', LBracket),
    (r'\]', RBracket),
    (r'\{', LBrace),
    (r'\}', RBrace),
    (r'\,', CommaT),
    (r'(?<="{1}).*?(?=")', STRLITERAL),
    (r'\"', QuoteT),
    (r'\.', PeriodT),
    (r'\-?[0-9]*\.[0-9]+', ValueR),
    (r'\+', AddT),
    (r'-', AddT),
    (r'\|\|', AddT),
    (r';', Semicolon),

我的匹配循环是这样的:

def lexer(input, tokenFormats):
    pos = 0
    tokens = []
    while pos < len(input):
        match = None
        for tokenFormat in tokenFormats:
            pattern, tag = tokenFormat
            regex = re.compile(pattern)
            match = regex.match(input,pos) #Essentially Build Lexeme
            if match:
                lexeme = match.group(0)
                if tag:
                    if tag == Identifier and len(str(lexeme)) > 27: #rough fix to check length. Very hacky
                        sys.stderr.write('Illegal length for identifier: %s\n' % lexeme)
                        break;
                    attr = checkForAttribute(lexeme,tag)
                    token = (lexeme,tag,attr)
                    tokens.append(token)
                    break
                else:
                    break
        if not match:
            sys.stderr.write('Illegal or unknown character: %s\n' % input[pos])
            pos = pos + 1
        else:
            pos = match.end(0)
    return tokens

【问题讨论】:

  • 切向,但 C 标识符也允许以 _ 开头。
  • 啊我的错。在我的词法分析器中,我不应该接受它们。我会编辑。
  • 除非您展示如何应用正则表达式,否则无法说出问题所在。
  • 我添加了一些代码。

标签: python regex python-3.x


【解决方案1】:

尝试锚定你的表情:

r'^[A-Za-z][A-Za-z0-9_]*$'

这要求整个标识符与表达式匹配,而不仅仅是其中的一部分,因为您将表达式锚定到字符串的开头和结尾。这可以防止部分字符串匹配。

【讨论】:

  • 我输入了那个,现在我什么都不匹配?想知道这是否是我如何为词法分析器提供输入文件的问题。我正在输入文件中的整个字符流并遍历该流和我的正则表达式以匹配令牌。
【解决方案2】:

如果@符号是您唯一关心的问题,试试这个r'[a-zA-Z]@?[a-zA-Z0-9_]+'

【讨论】:

  • 如果他有类似的东西会发生什么:testid2@entifier_?
  • 抱歉,我希望它拒绝整个“标识符”不匹配的部分。
【解决方案3】:

如果您也想允许@,您可以使用以下正则表达式:

r'[A-Za-z][A-Za-z0-9_]*@?[A-Za-z0-9_]*'

已测试: https://regex101.com/r/vlt8qo/3/

但是按照您的问题描述:

我正在定义一个正则表达式来匹配我定义的标识符 - 标识符必须以一个字母开头,后跟任意数量的字母、数字和下划线。

看起来有些不一致,因为 @ 未定义为您的标识符的一部分...

在帖子中进行编辑后:

我已将我的正则表达式调整为 ->

r'(?<=[\(\)\]\[\-=\+\s\n\t,;\|\.\"])[A-Za-z][A-Za-z0-9_]*(?=[\(\)\]\[\-=\+\s\n\t,;\|\.\"])|^[A-Za-z][A-Za-z0-9_]*(?=[\(\)\]\[\-=\+\s\n\t,;\|\.\"])'

并在几个模式上对其进行了测试@

https://regex101.com/r/vlt8qo/5/

【讨论】:

  • 抱歉,我对此进行了编辑。我只是希望它完全拒绝潜在的标识符。现在它正在匹配它的一部分。
  • 我运行了它,现在它拒绝了该行的每个字符。我在想我的代码如何遍历我正在检查的文件时遇到问题。上面的代码应该会有所启发。我只是想找到一个解决方案,而不必完全重写所有内容。
猜你喜欢
  • 2013-07-17
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 2011-12-19
  • 2013-10-19
  • 2019-10-22
相关资源
最近更新 更多