例如:
如果字符串是'“normal”script' - 输出应该显示substring normal
是双引号,而子串script
不是。
要从字符串中跟踪双引号子字符串,我尝试使用正则表达式:
r'“([^”] *)“'
我们可以使用split()
方法来获取没有双引号的子字符串,但我正在寻找一种有效的方法。
下面是我尝试过的代码 - 它返回双引号的子串列表。
import re
def demo(text):
matches = re.findall(r'"([^"]*)"', text)
return matches
a = demo('"normal" string "is here"')
print(a)
除了找到双引号子串之外,我还在寻找不是双引号的子串。
例如,demo('"normal" string "is here"')
的输出应为:
双引号:['normal', 'is here']
非双引号:['string']
答案 0 :(得分:1)
您可以在同一个正则表达式中搜索带引号和双引号的字符串。
import re
def dequote(s):
return re.findall(r'(?:"([^"]*)")|([^"]*)', s)
print(dequote('"normal" script'))
print(dequote('another "normal" script with "extra words in it"'))
通知返回的元组列表包含带引号和非带引号的字符串。引用的字符串位于元组的第一个元素中,非引用的字符串位于第二个元素中。
如果您希望将列表分开,则将它们分开是一件简单的事情。
result = dequote('another "normal" script with "extra words in it"')
result_quoted = [t[0].strip() for t in result if t[0]]
result_unquoted = [t[1].strip() for t in result if t[1]]
print("double quoted: {}\nnot double quoted{}".format(
result_quoted, result_unquoted))
整个计划的输出:
$ python x.py
[('normal', ''), ('', ' script'), ('', '')]
[('', 'another '), ('normal', ''), ('', ' script with '), ('extra words in it', ''), ('', '')]
double quoted: ['normal', 'extra words in it']
not double quoted['another', 'script with']
请注意,您暗示基于re
的解决方案将比基于str.split()
的解决方案更快。我不相信这一点。考虑这两个解决方案:
def dequote_re(s):
result = re.findall(r'(?:"([^"]*)")|([^"]*)', s)
result_quoted = [t[0].strip() for t in result if t[0]]
result_unquoted = [t[1].strip() for t in result if t[1]]
return result_quoted, result_unquoted
def dequote_split(s):
result = s.split('"')
result_unquoted = [item.strip() for item in result[0::2] if item]
result_quoted = [item.strip() for item in result[1::2] if item]
return result_quoted, result_unquoted
他们给出了相同的答案。也许你应该运行timeit来找到哪个更快。
答案 1 :(得分:1)
使用regex模块:
>>> import re, regex
>>> s='"normal" string "is here"'
>>> re.findall(r'"([^"]*)"', s)
['normal', 'is here']
# change \w to appropriate character class as needed
>>> regex.findall(r'"[^"]*"(*SKIP)(*F)|\w+', s)
['string']
# or a workaround, remove double quoted strings first
>>> re.findall(r'\w+', re.sub(r'"([^"]*)"', '', s))
['string']
有关详细说明,请参阅Using (*SKIP)(*FAIL) to Exclude Unwanted Matches。简单地说,将(*SKIP)(*F)
追加到正则表达式,你要排除并使用交替定义你需要的那些
答案 2 :(得分:0)
我知道split()
是最快的replace()
比正则表达式快,所以:
output = '"normal" script'.replace('"', '').split()
输出:['normal', 'script']
执行时间:3.490e-05 seconds
使用正则表达式可以获得时间0.2e-04
和0.3e-04
答案 3 :(得分:0)
如果你有相当大的字符串,你可以使用正则表达式来计算事件并设法将它分成更小的部分(取决于你期望得到的和从哪里获得)。
看来你的子串就是单词。 对于双引号或非双引号字符串,您可以按子串分割并将其作为列表进行分割。
通过双引号或非双引号分割可能需要创建两个列表。
通过单词分词,您可以创建单个单词列表,并在输出时检查双引号。
两种情况的成本几乎相同,具体取决于您获得的字符串大小。
我建议使用https://regexr.com并尝试尽可能多地获取您可以处理的字符串。
我最好的。