首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RegEx:如果“这个条件”,“不要返回其余的”?

RegEx:如果“这个条件”,“不要返回其余的”?
EN

Stack Overflow用户
提问于 2021-10-11 15:30:51
回答 2查看 63关注 0票数 2

我使用RegEx搜索包含文件路径列表的多行字符串。

目标是:如果匹配在文件夹名中-只返回此文件夹路径(如果它们匹配,不要返回任何子文件夹)。如果匹配位于文件名中,则返回整行(完整文件路径)。

当前使用的模式返回整个字符串:.*([^\\]*(John|Smith|Junior)){2}.*

期望返回的字符串:

代码语言:javascript
运行
复制
C:\temp\John Smith Junior\file.pdf -> C:\temp\John Smith Junior\
C:\temp\John Smith Junior\John Smith Junior\file.pdf -> C:\temp\John Smith Junior\
C:\temp\John Smith Junior file.pdf -> C:\temp\John Smith Junior file.pdf

我试着添加到模式的末尾,比如:\n或(\n)或(?!=.+),但这并不完全符合我的要求。谢谢你的帮助!

演示:https://regex101.com/r/98d6Ed/1

代码语言:javascript
运行
复制
.*([^\\]*(John|Smith|Junior)){2}.*
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-11 15:41:56

使用(John|Smith|Junior)是一个替代方案--约翰、史密斯或朱尼尔。

如果您想要匹配整个字符串John Smith Junior,可以在模式中使用它。

在Python少年中,您可以使用一个if子句来测试第一次出现re之后的\

如果它在那里,那么就是匹配,否则匹配除\以外的任何字符,直到字符串结束。

代码语言:javascript
运行
复制
^.*?\bJunior\b(\\)?(?(1)|.*)
  • 字符串的^开始
  • .*?\bJunior\b匹配青少年第一次发病
  • (\\)?可选择地捕获第1组中的\
  • (?(1)|.*)条件,使用(?(1)测试组1是否存在,即匹配,否则使用.*匹配字符串的其余部分。

Regex演示 x- Python演示

代码语言:javascript
运行
复制
import re

strings = [
    r"C:\temp\John Smith Junior\file.pdf",
    r"C:\temp\John Smith Junior\John Smith Junior\file.pdf",
    r"C:\temp\John Smith Junior file.pdf"
]

for s in strings:
    m = re.match(r".*?\bJunior\b(\\)?(?(1)|.*)", s)
    if m:
        print(m.group())

输出

代码语言:javascript
运行
复制
C:\temp\John Smith Junior\
C:\temp\John Smith Junior\
C:\temp\John Smith Junior file.pdf

另一个选项,匹配至少2倍交替中的一个名称,然后匹配除换行符或反斜杠以外的任何字符:

代码语言:javascript
运行
复制
^.*?\\[^\\\n]*\b(?:John|Smith|Junior)\s+(?:John|Smith|Junior)\b[^\\\n]*

Regex演示

票数 2
EN

Stack Overflow用户

发布于 2021-10-11 16:09:47

我建议不要使用regexp,只需使用优秀的pathlib类即可。

代码语言:javascript
运行
复制
from pathlib import PureWindowsPath

lines = [
    r"C:\temp\John Smith Junior\file.pdf",
    r"C:\temp\John Smith Junior\John Smith Junior\file.pdf",
    r"C:\temp\John Smith Junior file.pdf"
]

def first_match(path, parts):
  for parent in reversed(path.parents):
    if any(part in str(parent) for part in parts):
      return parent
  return None

for line in lines:
  path = PureWindowsPath(line)
  parts = ('John', 'Smith', 'Junior')
  directory_match = first_match(path, parts)
  if directory_match:
    print(directory_match)
  else:
    if any(part in path.name for part in parts):
      print(path)

第三种选择是使用pathlib将部件解析为目录和文件名,如上面所示,然后使用regexp进行匹配,例如简单地使用(John|Smith|Junior)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69528803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档