如何拆分和替换引号中除外的字符串,包括 python 中的引号

问题描述 投票:0回答:1

我在制作 lisp 方言,我有一个函数

compute
,例如
(+ 1 2 (- 2 1))
('+', '1', '2', ('-', '2', '1'))
.

这是我目前的实现。

import shlex

def compute(expr):
    expr = expr.replace('(', '( ').replace(')', ' )')
    expr = shlex.split(expr)

    new = ''
    for index, i in enumerate(expr):
        if   i == '(': new += i
        elif i == ')': new += i
        elif (not(len(expr) == 1 or len(expr) == 0)) and expr[index+1] == ')':
            new += ('"' + i + '"')
        else:
            new += ('"' + i + '",')
    
    expr = eval(new)
    return expr

这适用于所有表达式,除了使用字符串的表达式。

  1. (
    )
    将变成
    ( 
     )
    即使在字符串中
  2. 如你所见。我正在使用
    shlex
    来不拆分字符串内的空格,但我想要它以便包含引号。所以
    (println "Hello, world!")
    应该变成
    ('println', '"Hello, world!"')
    而不是
    ('println', 'Hello, world!')
  3. \"
    彻底打破一切。
python replace split lisp
1个回答
0
投票

你必须在

poxis=False
调用中使用
shlex.split()
标志,否则它会去掉双引号:

shlex.split(expr)
['(', 'println', 'Hello, world!', ')']

在哪里:

shlex.split(expr, posix=False)
['(', 'println', '"Hello, world!"', ')']

但是,这并不能完全解决问题。您将不得不修改将

"
附加到
i
的代码:

new = ''
for index, i in enumerate(expr):
    if   i == '(': new += i
    elif i == ')': new += i
    elif (not(len(expr) == 1 or len(expr) == 0)) and expr[index+1] == ')':
        if i[0] == "\"" and i[-1] == "\"": # Check if i starts/ends with "
            new += ('\'' + i + '\'') # Append single quote
        else:
            new += ('"' + i + '"') # Append double quote
    else:
        new += ('"' + i + '",')

现在有了所有的变化,

print(compute('(println "Hello, world!")'))
返回:

('println', '"Hello, world!"')

注意

compute("(+ 1 2 (- 2 1))")
仍然按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.