【问题标题】:How to account for special characters when splitting string in python在python中拆分字符串时如何考虑特殊字符
【发布时间】:2020-10-14 18:42:21
【问题描述】:

我有几个“[一个或多个单词] [数字] [一个或多个单词]”形式的字符串,我想将它们分成两个字符串和数字。例如,如果字符串是:

"A sample string 20 something"

我要获取:

str1 = "A sample string"
numb = 20
str2 = 'something'

我(几乎)使用以下代码实现了我的目标:

for s in row.split():
    if s.isdigit():
        quants = s
temp = row.split("{}".format(quants))
str1 = temp[0].strip()
str2 = temp[1].strip()

这适用于大多数情况。但是,有两个我无法处理的异常:

  1. 如果数字在括号内,我希望它被计为一个字符串。例如:

    “一些文字(仅作为 1 个示例)还有 2 个单词”

    我想要 str1 = "Some text (just as 1 example)"

  2. 有时数字以特殊字符(Unicode?)、¼、½ 和 ¾ 表示。我该如何解释这些?

我怀疑答案是使用正则表达式而不是分隔符,但我还不能真正掌握如何使用它们。

【问题讨论】:

  • 一些备注:1)split()不会帮你;您的解决方案仅适用于个位数 2)将括号中的数字视为文本的要求需要不同的方法。 3)使用正确的编码语句,您可以在代码中包含与您的问题相同的分数。
  • 1) 实际上,我的解决方案也适用于超过 1 位的数字,只要它们之间没有空格,这满足我必须处理的字符串的特征。 2)什么方法? 3)编码语句是什么意思?这些不仅仅是分数,而是 unicode(?) 字符(即 ¼ 不是 1/4)
  • 对不起,我已经编辑了答案以更好地满足您的需求,除了特殊字符,您的意思是½ = 1/2?

标签: python split


【解决方案1】:

您可以使用带有 3 个捕获组的正则表达式,然后获取这些组的值。

^(\w+(?: \w+)*(?: \([^()]*\))?) (\d+|[¼½¾]) (\w+(?: \w+)*)$

解释

  • ^ 字符串开始
  • ( 捕获第 1 组
    • \w+(?: \w+)* 匹配 1+ 个单词字符,可选用空格和 1+ 个单词字符重复
    • (?: \([^()]*\))? 可选地匹配一个空格并形成从左到右括号
  • ) 关闭分组并匹配空格
  • (\d+|[¼½¾]) 捕获组 2 匹配列出的 ¼½¾ 中的 1+ 位或 1 位和空格
  • (\w+(?: \w+)*) 捕获 group 3 匹配 1+ 个单词字符,并可选择重复前面的空格
  • $字符串结束

Regex demo | Python demo

示例代码

import re

regex = r"(\w+(?: \w+)*(?: \([^()]*\))?) (\d+|[¼½¾]) (\w+(?: \w+)*)"
s = "Some text (just as 1 example) ¼ more words"
match = re.match(regex, s)
if match:
    print(match.group(1))
    print(match.group(2))
    print(match.group(3))

输出

Some text (just as 1 example)
¼
more words

一个更广泛的模式,使用.* 匹配除换行符以外的任何字符,而不是使用\w+

^(.*(?:\([^()]*\))?) (\d+|[¼½¾]) (.+)

Regex demo

【讨论】:

  • 完美!正则表达式演示工具也很棒。非常感谢!
【解决方案2】:

我通过用数字替换正则表达式来调整 this 答案

import re
l = re.compile("((?<=\d)(?=\D)|(?=\d)(?<=\D))(?![^\(]*\))").split(test)

给了我这个:

['A sample string ', '20', ' something']

在这里测试:https://regex101.com/r/zT2dF9/53

((?&lt;=\d)(?=\D)|(?=\d)(?&lt;=\D)) 可以分为两个步骤: (?(?<=\d) 完成)后跟任何类型的非数字`(?=\D)'

反之亦然(?=\d)(?&lt;=\D) 搜索非数字后跟数字

这由(?![^\(]*\)) 连接以忽略括号中的内容

有关正则表达式文字的详细信息,请查看:https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285

【讨论】:

  • 您能解释一下吗?我的代码已经可以通过这种方式分解字符串。这段代码能处理我上面提到的两个异常吗?
猜你喜欢
  • 2022-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多