Python正则表达式:如何检查字符串中的一个字符是否在正则表达式匹配的子字符串范围内?

3
我有一个正则表达式模式,我在一大段文本(单个字符串)上使用它。原始文本中的多个不连续区域与正则表达式匹配。现在,我正在尝试构建一个状态机,遍历文本并根据位置处的字符以及该位置是否在正则表达式匹配的范围内执行不同的操作。
使用 RE.finditer(text),我可以找到所有子字符串,并提取它们的范围,因此我有一个元组列表可供使用,例如:
(1, 5) (10, 15) (20, 55) 等等。
有了这些信息,给定字符串中的字符索引,我可以编写算法来查看该字符是否是正则表达式字符串的一部分。例如,给定字符6,我可以遍历跨度列表并确定它不是匹配的子字符串的一部分。
有更好的方法吗?
提前感谢您,
JW

听起来你想编写一个解析器FSM,其中(除其他事项外)仅在未转义时对逗号字符进行标记化。你真的想编写自己的状态机,而不仅仅是语法,并让antlr/lex为您创建FSM吗? - smci
有点儿模糊,我的词法分析器和语法分析器(lex/yacc)不太熟练 :)。 - wk1989
当你只需要一个匹配标识符内转义逗号的正则表达式时,就不需要编写解析器FSM了。那么,你想将*bbbb/,ccccc*作为一个令牌捕获还是三个令牌? - smci
在一个标记中,如果它们是转义序列的一部分,我会忽略逗号。 - wk1989
好的,我在我的答案中添加了一个正则表达式来实现这个。 - smci
2个回答

1

编辑:听起来您想编写自己的解析器FSM,其中(除其他事项外)将标记逗号字符,仅当它们未被转义时。 以下正则表达式适用于可能包含转义逗号的标识符。您可以在antlr / lex中使用它:

input = r'aaaaa,bbbb/,ccccc,dddddd,'

pat = re.compile(r'((\w+|/,)+)')

for mat in re.finditer(pat, input):
    ... do stuff with mat.group(0)

(原始答案:这可能是一个好的解决方案,但你没有给我们足够的上下文来判断。

字符是单个出现还是多次出现?如果它只出现一次,你可以检查string.find(char)的索引是否在正则表达式匹配的范围内。

字符是任意字符吗?请给我们一个具体的例子。为什么要按字符进行操作?假设您不是顺序检查多个字符?

您期望的结果是布尔值(“是的,char被找到在某个正则表达式匹配的范围内”)吗?如果char在正则表达式匹配之外被找到,您会怎么处理?


我有一个状态机,它遍历字符串并根据字符的类型以及字符是否是正则表达式匹配的一部分执行特定的操作。例如,如果字符是“,”并且不是正则表达式匹配的子字符串的一部分(所以我想忽略所有在特定正则表达式匹配的子字符串中的“,”),那么就要做某些操作。因此,我将处理多个相同字符的实例,并需要知道每个字符是否是正则表达式匹配的子字符串的一部分。希望这样能够解释清楚,谢谢。 - wk1989
仍然缺乏上下文。请提供一个具体的字符串输入和输出示例。你为什么要编写一个通用状态机——这是你的目标还是你选择的实现方式?你为什么要尝试将逗号字符与正则表达式匹配——这是为了解决什么具体问题? - smci
如果你只想忽略在你的匹配中一定范围内的 ignoreChars,那么你可以在它们上应用 string.translate(...deleteChars),对吗? - smci
这只是一个任意的例子:扫描 aaaaa,bbbb/,ccccc,dddddd,我想保存在 2 个“,”之间的字符串,但是 /,被视为特殊的转义序列而不是实际的“,”。因此,我遍历字符串,每次遇到“,”时保存文本,但是如果遇到“/,”,我不想保存文本。因此,我创建了一个正则表达式来匹配字符串中的所有转义序列,并根据这些信息,每当我的状态机遇到“,”时,我需要知道该“,”是否是转义序列的一部分。 - wk1989
我实际上想要保留这些字符,所以不能只是删除它们。到目前为止,我已经知道了我提出的解决方案可以工作,但我很好奇是否有更优雅的解决方案。 - wk1989
听起来你一开始就不想匹配可选的尾随逗号。如果是这样,要么使用 input.split(','),要么使用带有可选前瞻断言的正则表达式来捕获逗号 *(?=,)?*。 - smci

1

编辑 这是一个正则表达式,它将获取在,之间的文本,忽略转义的,

(?=<,)(?:[^,]|(?=</),)(?=,)

原始答案 这里是一些伪 Python 代码,应该可以实现你想要的功能:

pattern = re.compile(...)
pos = 0

while (match = pattern.search(haystack, pos)) {
  for (i in range(pos, match.start)
    //These chars are outside the match.

  for (i in group(0))
    //The chars are in the match

  pos = match.end

//Finish with the rest of the chars not matched
for (i in range(pos, len(haystack))
  //These chars are outside the match.

2
“haystack”? 那太 PHP 了。 - NullUserException

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接