python使用单词列表中的任意单词拆分字符串

python使用单词列表中的任意单词拆分字符串,python,string,list,split,Python,String,List,Split,我有一张单子 trails = ("Fire trail", "Firetrail", "Fire Trail", "FT", "firetrail") 我需要根据这些单词中的任何一个拆分另一个字符串。 比如说,如果要检查的名称是: 贫困点 雪松党消防步道 邮箱跟踪 地毯蛇溪消防车道 美丽沟壑火烧迹地-罗亚尔NP 我想将其修改为如下所示: 贫困点 雪松党 信箱 地毯蛇溪 美沟 在跟踪列表中的一个单词之前拆分,只复制前面的部分 谢谢 我应该补充一点,我的代码以: for f in arc

我有一张单子

trails = ("Fire trail", "Firetrail", "Fire Trail", "FT", "firetrail")
我需要根据这些单词中的任何一个拆分另一个字符串。
比如说,如果要检查的名称是:

  • 贫困点
  • 雪松党消防步道
  • 邮箱跟踪
  • 地毯蛇溪消防车道
  • 美丽沟壑火烧迹地-罗亚尔NP
我想将其修改为如下所示:

  • 贫困点
  • 雪松党
  • 信箱
  • 地毯蛇溪
  • 美沟
在跟踪列表中的一个单词之前拆分,只复制前面的部分

谢谢

我应该补充一点,我的代码以:

for f in arcpy.da.SearchCursor("firetrail_O_noD_Layer", "FireTrailName", None, None):
...     if any(var in str(f[0]) for var in trail):
...         new_field = *that part of string without any fire trails and anything after it*
str(f[0])指的是第一个列表中的名称
新字段是指我在第二个列表中的名字,我需要创建这些名字,我相信这就是你要找的。如果希望标记不区分大小写,还可以添加类似so
res=re.split(regex,s,re.IGNORECASE)的标记
re.IGNORECASE
。有关更多文档,请参阅

import re
trails = ("Fire trail", "Firetrail", "Fire Trail", "FT", "firetrail")

# \b means word boundaries.
regex = r"\b(?:{})\b".format("|".join(trails))

s = """Poverty Point FT
Cedar Party Fire Trails
Mailbox Trail
Carpet Snake Creek Firetrail
Pretty Gully firetrail - Roayl NP"""

res = re.split(regex, s)
更新:

如果你一行一行地走,不想走到尽头,你可以这样做:

import re
trails = ("Fire trail", "Firetrail", "Fire Trail", "FT", "firetrail", "Trail", "Trails")

# \b means word boundaries.
regex = r"\b(?:{}).*".format("|".join(trails))

s = """Poverty Point FT
Cedar Party Fire Trails
Mailbox Trail
Carpet Snake Creek Firetrail
Pretty Gully firetrail - Roayl NP"""

res = [r.strip() for r in re.split(regex, s)]
您可以在此处使用:


可以使用正则表达式执行此操作,例如:

def make_matcher(trails):
    import re
    rgx = re.compile(r"{}".format("|".join(trails)))
    return lambda txt: rgx.split(txt)[0]

>>> m = make_matcher(["Fire trail", "Firetrail", "Fire Trail", "FT", "firetrail"])
>>> examples = ["Poverty Point FT", "Cedar Party Fire Trails", "Mailbox Trail", "Carpet Snake Creek Firetrail", "Pretty Gully firetrail - Roayl NP"]
>>> for x in examples:
...     print(m(x))
Poverty Point 
Cedar Party 
Mailbox Trail
Carpet Snake Creek 
Pretty Gully 

请注意,在本例中,保留了eg
Firetrail
出现之前的尾随空间。那可能不是你想要的

看来,需求和解决方案应该得到澄清并反复测试,我在这里提供 建议的解决方案,包括与
pytest
一起使用的测试套件

首先,创建
test_trails.py
文件:

import pytest


def fix_trails(trails):
    """Clean up list of trails to make sure, longest phrases are processed
    with highest priority (are sooner in the list).

    This is needed, if some trail phrases contain other ones.
    """
    trails.sort(key=len, reverse=True)
    return trails


@pytest.fixture
def trails():
    phrases = ["Fire trail", "Firetrail", "Fire Trail",
               "FT", "firetrail", "Trail", "Fire Trails"]
    return fix_trails(phrases)


def remove_trails(line, trails):
    for trail in trails:
        if trail in line:
            res = line.replace(trail, "").strip()
            return res.replace("  ", " ")
    return line


scenarios = [
    ["Poverty Point FT", "Poverty Point"],
    ["Cedar Party Fire Trails", "Cedar Party Fire"],
    ["Mailbox Trail", "Mailbox"],
    ["Carpet Snake Creek Firetrail", "Carpet Snake Creek"],
    ["Pretty Gully firetrail - Roayl NP", "Pretty Gully - Roayl NP"],
]


@pytest.mark.parametrize("scenario", scenarios, ids=lambda itm: itm[0])
def test(scenario, trails):
    line, expected = scenario
    result = remove_trails(line, trails)
    assert result == expected
该文件定义了从处理的行中删除不需要的文本的函数,以及包含 测试用例
test\u trails

要测试它,请安装
pytest

$ pip install pytest
然后运行测试:

$ py.test -sv test_trails.py
========================================= test session starts ==================================
=======
platform linux2 -- Python 2.7.9, pytest-2.8.7, py-1.4.31, pluggy-0.3.1 -- /home/javl/.virtualenvs/stack
/bin/python2
cachedir: .cache
rootdir: /home/javl/sandbox/stack, inifile:
collected 5 items

test_trails.py::test[Poverty Point FT] PASSED
test_trails.py::test[Cedar Party Fire Trails] FAILED
test_trails.py::test[Mailbox Trail] PASSED
test_trails.py::test[Carpet Snake Creek Firetrail] PASSED
test_trails.py::test[Pretty Gully firetrail - Roayl NP] PASSED

================ FAILURES ==================
______ test[Cedar Party Fire Trails] _______

scenario = ['Cedar Party Fire Trails', 'Cedar Party Fire']
trails = ['Fire Trails', 'Fire trail', 'Fire Trail', 'Firetrail', 'firetrail', 'Trail', ...]

    @pytest.mark.parametrize("scenario", scenarios, ids=lambda itm: itm[0])
    def test(scenario, trails):
        line, expected = scenario
        result = remove_trails(line, trails)
>       assert result == expected
E       assert 'Cedar Party' == 'Cedar Party Fire'
E         - Cedar Party
E         + Cedar Party Fire
E         ?            +++++

test_trails.py:42: AssertionError
======== 1 failed, 4 passed in 0.01 seconds ============
py.test
命令在文件中发现测试用例,查找输入参数,使用注入 将
trails
的值放入其中,测试用例的参数化提供了场景 参数

然后,您可以微调功能
remove_trails
trails
列表,直到全部通过

完成后,您可以将
remove_trails
功能移动到需要的位置(可能包括。
trails
list)


您可以使用这种方法来测试针对您的问题提出的任何解决方案。

好吧,这里有一种更动态的方法来执行任务

import re

courses = r"""
Poverty Point FT
Cedar Party Fire Trails
Mailbox Trail
Carpet Snake Creek Firetrail
Pretty Gully firetrail - Roayl NP
"""

trails = ("Fire trail", "Firetrail", "Fire Trail", "FT", "firetrail")

rx_str = '|'.join(trails)
rx_str = r"^.+?(?=(?:{0}|$))".format(rx_str)

rx = re.compile(rx_str, re.IGNORECASE | re.MULTILINE)

for course in rx.finditer(courses):
    print(course.group())
正如您所注意到的,我正在动态地将列表转换为正则表达式,而无需硬编码。脚本将呈现以下结果:

Poverty Point 
Cedar Party 
Mailbox Trail
Carpet Snake Creek 
Pretty Gully 

您的字符串是在文件中还是在列表中?你们有什么样的格式?从你们的问题看来,你们需要的是去掉行的尾随部分,而不是拆分。对吗?gtlambert,我的字符串是成行的(如果有意义的话)。我从一个领域,通过一个循环一个接一个地阅读。它是tuple的一部分。然后我把它称为str(f[0])。我希望这是有道理的。我对python非常陌生!简,我不知道你的意思!我正在一个接一个地浏览记录,这就是为什么我把它们列为要点。“我回答了你的问题吗?”利达:是的,你回答了我的问题。在python中,
split
表示将字符串拆分为多个部分,创建一个列表<另一方面,如果可能的话,代码>条带
会删除字符串的一部分。你的问题使用了单词
split
,这让我有点困惑。您的意思是
strip
。对于
Pretty Gully firetrail-Roayl NP
,这个脚本不是呈现了错误的结果吗?OP期待的只是
Pretty Gully
@Saleem我给了他解决方案从我的头上写下来,他应该修改他的词组列表,让它按照他想要的方式工作。只是想确保任何新来者都不会感到困惑+1月1日,这不是我需要的方式。在印刷版的声明中仍然有firetrail的字样:[“贫困点”,“雪松党火路”,“邮箱小径”,“地毯蛇溪”,“美丽的沟壑firetrail-Roayl NP']。我需要火线,火线-我要走了。我已经有了一个循环,所以不需要为多行代码。如果只有一行,你会怎么做?@lida,我明白了,你既不要求拆分,也不要求将行的结尾条带化,但你想删除该文本。Bharel。谢谢我跑了。结果不是我所需要的。。从您的代码中,我得到:[“贫困点”、“\nCedar Party Fire Trails\n邮箱Trail\nCarpet Snake Creek”、“\nPrety Gully”、“-Roayl NP”]。然而,我不需要“火焰轨迹”或“轨迹”,也不需要“皇家NP”(它是在轨迹之后,所以需要删除),这样我就可以将值复制到另一个字段中。如果我的列表中只有一行(但你不知道是哪一行),你会怎么写?(因为我已经有一个循环要一行一行地进行了。刚刚为我的桌子调整了你的版本,它按照我想要的方式工作。谢谢。虽然我不确定空间,但我认为这在现阶段不是一个问题。非常感谢!donkopotamus,出于某种原因,我的一些案例没有被提起。尽管它们看起来完全一样,例如Aberdare FireTrail,Winters Fire Trail-Karuah NP,地毯蛇溪Fire Trail。这是因为空间问题还是其他原因?请您解释一下rgx表达式的作用。谢谢!@lida
m(“Aberdare Fire Trail”)
=>
'Aberdare'
…这不是您所期望的吗
Poverty Point 
Cedar Party 
Mailbox Trail
Carpet Snake Creek 
Pretty Gully