使用“re.finditer()”方法查找字符串中未加引号的单词的索引
Find indexes of unquoted words in a string using `re.finditer()` method
我试图找到字符串中未加引号的单词的位置(索引),但我的所有测试都没有成功。
对于字符串:string='foo "bar" baz'
我想得到
(0, 3) # This for foo
(10, 13) # This for baz
# I'd like to skip the quoted "bar"
但是,我尝试的每个正则表达式都包含引用的 'bar'
或其中的一部分:
string='foo "bar" baz'
_RE_UNQUOTED_VALUES = re.compile(r"([^\"']\w+[^\"'])")
print([m.span() for m in _RE_UNQUOTED_VALUES.finditer(string)])
输出:[(0, 4), (5, 8), (9, 13)]
或使用:
_RE_UNQUOTED_VALUES = re.compile(r"(?!(\"|'))\w+(?!(\"|'))")
# Outputs [(0, 3), (5, 7), (10, 13)]
用正则表达式不行吗?我是不是误解了 finditer()
的工作原理?
您可以使用
import re
string="foo 'bar' baz"
ms = re.finditer(r"""\b(?<!['"])\w+\b(?!['"])""", string)
print([(x.start(), x.end()) for x in ms])
# => [(0, 3), (10, 13)]
参见Python demo。
\b(?<!['"])\w+\b(?!['"])
正则表达式首先匹配单词边界,然后 (?<!')
否定后视如果紧邻左侧有 '
/"
字符则匹配失败,然后匹配一个或多个单词字符,再次检查单词边界位置,如果右侧紧邻 '
/"
字符,则 (?!['"])
否定先行匹配失败。
参见regex demo。
您还可以使用:
import re
string='foo "bar" baz'
_RE_UNQUOTED_VALUES = re.compile(r"(?<!['\"\w])\w+(?![\"'\w])")
print([m.span() for m in _RE_UNQUOTED_VALUES.finditer(string)])
输出:
[(0, 3), (10, 13)]
在这种情况下,使用 \w
以及否定环视中的引号字符会强制引擎仅匹配未被引号包围的整个单词。
使用 .index
而不是正则表达式怎么样?这样它就更具可读性和可扩展性。例如:
strstr=lambda s, sub: (s.index(sub), s.index(sub)+len(sub))
strstr('foo "bar" baz', 'foo')
# (0, 3)
strstr('foo "bar" baz', 'baz')
# (10, 13)
但是,如果您不知道输入并且需要使用正则表达式,@Wiktor 的回答会更好。
我试图找到字符串中未加引号的单词的位置(索引),但我的所有测试都没有成功。
对于字符串:string='foo "bar" baz'
我想得到
(0, 3) # This for foo
(10, 13) # This for baz
# I'd like to skip the quoted "bar"
但是,我尝试的每个正则表达式都包含引用的 'bar'
或其中的一部分:
string='foo "bar" baz'
_RE_UNQUOTED_VALUES = re.compile(r"([^\"']\w+[^\"'])")
print([m.span() for m in _RE_UNQUOTED_VALUES.finditer(string)])
输出:[(0, 4), (5, 8), (9, 13)]
或使用:
_RE_UNQUOTED_VALUES = re.compile(r"(?!(\"|'))\w+(?!(\"|'))")
# Outputs [(0, 3), (5, 7), (10, 13)]
用正则表达式不行吗?我是不是误解了 finditer()
的工作原理?
您可以使用
import re
string="foo 'bar' baz"
ms = re.finditer(r"""\b(?<!['"])\w+\b(?!['"])""", string)
print([(x.start(), x.end()) for x in ms])
# => [(0, 3), (10, 13)]
参见Python demo。
\b(?<!['"])\w+\b(?!['"])
正则表达式首先匹配单词边界,然后 (?<!')
否定后视如果紧邻左侧有 '
/"
字符则匹配失败,然后匹配一个或多个单词字符,再次检查单词边界位置,如果右侧紧邻 '
/"
字符,则 (?!['"])
否定先行匹配失败。
参见regex demo。
您还可以使用:
import re
string='foo "bar" baz'
_RE_UNQUOTED_VALUES = re.compile(r"(?<!['\"\w])\w+(?![\"'\w])")
print([m.span() for m in _RE_UNQUOTED_VALUES.finditer(string)])
输出:
[(0, 3), (10, 13)]
在这种情况下,使用 \w
以及否定环视中的引号字符会强制引擎仅匹配未被引号包围的整个单词。
使用 .index
而不是正则表达式怎么样?这样它就更具可读性和可扩展性。例如:
strstr=lambda s, sub: (s.index(sub), s.index(sub)+len(sub))
strstr('foo "bar" baz', 'foo')
# (0, 3)
strstr('foo "bar" baz', 'baz')
# (10, 13)
但是,如果您不知道输入并且需要使用正则表达式,@Wiktor 的回答会更好。