XPath的substring()函数如何提取子字符串?

畫卷琴夢
发布: 2025-08-19 15:13:01
原创
771人浏览过
substring()函数用于从字符串中提取指定位置的子串,索引从1开始,常与substring-before()、substring-after()结合处理固定格式文本,适用于结构化字符串提取,而正则表达式更适合复杂模式匹配。

xpath的substring()函数如何提取子字符串?

XPath的

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
函数,简单来说,就是用来从一个字符串里“剪”出你想要的那一部分。有时候,我们从XML或HTML里抓取到的文本,往往不是我们想要的全部,可能只是一段日期、一个ID号,或者某个特定字段。这时候,
substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
函数就派上用场了,它能让你精确地定位并提取出目标子串。

解决方案

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
函数的基本语法是
substring(string, start, length)
登录后复制

  • string
    登录后复制
    :这是你想要操作的原始字符串。它可以是一个直接的字符串字面量,也可以是XPath表达式返回的节点文本内容(比如
    text()
    登录后复制
    或某个元素的路径)。
  • start
    登录后复制
    登录后复制
    登录后复制
    :这是你想要开始提取子字符串的位置。注意,XPath的索引是从1开始的,而不是像很多编程语言那样从0开始。 这是一个常见的“坑”,很容易让人混淆。
  • length
    登录后复制
    登录后复制
    :这是你想要提取的子字符串的长度。这个参数是可选的。如果你省略了它,
    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    会从
    start
    登录后复制
    登录后复制
    登录后复制
    位置开始,一直提取到字符串的末尾。

一些例子:

  1. 提取从某个位置开始到结尾的子串: 假设我们有一个字符串 "Hello World!",我们想提取 "World!"。

    substring("Hello World!", 7)
    登录后复制
    结果是:"World!"

    这里,'H'是第1位,'e'是第2位,以此类推,空格是第6位,'W'是第7位。所以从第7位开始提取,一直到字符串末尾。

  2. 提取指定长度的子串: 从 "Hello World!" 中提取 "Hello"。

    substring("Hello World!", 1, 5)
    登录后复制
    结果是:"Hello"

    从第1位开始,提取5个字符。

  3. 结合节点文本提取: 假设XML中有一个

    <data>2023-10-26</data>
    登录后复制
    节点,我们只想提取年份 "2023"。
    substring(/data/text(), 1, 4)
    登录后复制
    结果是:"2023"

    或者,如果只想提取月份 "10":

    substring(/data/text(), 6, 2)
    登录后复制
    结果是:"10"

    我的经验是,当你需要处理的字符串结构相对固定,或者可以通过简单的位置计算就能确定要截取的部分时,

    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    简直是神器,直接了当。

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
函数在实际应用中常见的“坑”有哪些?

说实话,用

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
函数,最容易让人头疼的,就是那个1-based索引。我们写代码习惯了0-based,一到XPath这里就得手动加1,或者在心里默默转换一下。我就经常因为这个,第一次尝试的时候结果总是差一位。比如,我想从“ABCD”里取“BC”,如果我习惯性地写
substring("ABCD", 1, 2)
登录后复制
(以为A是0),结果会是“AB”。正确的应该是
substring("ABCD", 2, 2)
登录后复制
。这种小细节,在调试复杂XPath表达式的时候,能让你抓狂半天。

另一个需要注意的点是,如果你的

start
登录后复制
登录后复制
登录后复制
位置超出了字符串的长度,或者
length
登录后复制
登录后复制
参数导致提取范围超出了字符串末尾,
substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
并不会报错。它会“尽力而为”。比如,
substring("Hello", 10)
登录后复制
会返回一个空字符串,因为第10位根本不存在。而
substring("Hello", 3, 10)
登录后复制
,虽然我们想提取10个字符,但从第3位('l')开始,后面只有3个字符了,它就会返回“llo”,不会因为长度不够而抛出异常。这种“静默失败”有时候反而更麻烦,因为你可能不知道自己是不是取到了一个不完整的字符串。所以,在使用前,最好能对字符串的长度有个大致的预判,或者结合
string-length()
登录后复制
函数做一些边界检查。

如何利用
substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
结合其他XPath函数实现更复杂的文本提取?

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
本身很直接,但它的威力在于能和XPath里其他字符串函数“组合拳”。比如,当你需要提取一个不固定位置但有明确前后标志的文本时,
substring-before()
登录后复制
登录后复制
登录后复制
substring-after()
登录后复制
登录后复制
登录后复制
就是它的好搭档。

举个例子,假设我们有这样的文本:

订单号: ORD-1234567890 状态: 已完成
登录后复制
,我们想提取订单号
ORD-1234567890
登录后复制
登录后复制
。 直接用
substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
有点难,因为订单号的长度不固定。但我们可以这样:

  1. 先用
    substring-after(., '订单号: ')
    登录后复制
    得到
    ORD-1234567890 状态: 已完成
    登录后复制
  2. 再对这个结果用
    substring-before(., ' 状态:')
    登录后复制
    得到
    ORD-1234567890
    登录后复制
    登录后复制

所以,完整的XPath表达式可能是:

substring-before(substring-after(/some/node/text(), '订单号: '), ' 状态:')
登录后复制

这看起来有点绕,但确实是解决这类问题的常用手段。 再比如,如果你想从一个URL中提取域名,而这个URL的格式不总是那么规整,但你知道它总是在

//
登录后复制
之后,可能在第一个
/
登录后复制
之前。
substring-before(substring-after(., '//'), '/')
登录后复制
就可以尝试提取出
www.example.com
登录后复制
之类的部分。当然,这只是一个简化版,实际的URL解析会复杂得多。

关键在于,

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
提供的是一种基于位置的裁剪能力,而
substring-before()
登录后复制
登录后复制
登录后复制
substring-after()
登录后复制
登录后复制
登录后复制
提供的是基于内容的裁剪能力。它们结合起来,就能处理很多看起来有点棘手的文本提取任务。我个人觉得,这种链式调用,就像是在一步步地“剥洋葱”,每次都剥掉一层不需要的,直到露出核心。

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
函数与正则表达式相比,各自的优势和适用场景是什么?

这是一个很有意思的对比。从我的经验来看,

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
和正则表达式(Regex)在处理字符串方面,就像是两把不同的工具,各有各的锋利之处。

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
的优势与适用场景:

  • 简洁直观: 当你需要从字符串的固定位置或已知长度处提取内容时,
    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    无疑是最直接、最易读的方案。比如,从一个固定格式的日期字符串“YYYYMMDD”中提取年份,
    substring(., 1, 4)
    登录后复制
    ,一目了然。
  • 性能开销小: 相比于复杂的正则表达式引擎,
    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    的操作通常更轻量,性能开销更小。对于大量字符串处理的场景,如果
    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    能满足需求,它通常是更优的选择。
  • XPath 1.0的唯一选择: 值得注意的是,XPath 1.0标准本身并不支持正则表达式。在很多老旧系统或某些特定环境中,你可能只能使用XPath 1.0。在这种情况下,
    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    以及
    substring-before()
    登录后复制
    登录后复制
    登录后复制
    substring-after()
    登录后复制
    登录后复制
    登录后复制
    就成了你进行字符串操作的“全部家当”。这确实是一种限制,但也迫使你更巧妙地利用这些基础函数。

正则表达式的优势与适用场景:

  • 强大的模式匹配: 正则表达式的真正强大之处在于其模式匹配能力。当字符串的结构不固定,或者你需要根据复杂的规则(如包含数字、字母、特定符号的组合,或者可变长度的序列)来提取内容时,正则表达式是不可替代的。比如,提取所有符合邮箱格式的字符串,或者从混杂的文本中识别出电话号码。
  • 灵活性高: 正则表达式可以处理各种复杂的边界条件、重复模式,甚至可以通过捕获组(capturing groups)一次性提取出多个感兴趣的部分。
  • XPath 2.0+支持: 幸运的是,从XPath 2.0开始,引入了对正则表达式的支持,通过
    matches()
    登录后复制
    ,
    replace()
    登录后复制
    ,
    tokenize()
    登录后复制
    等函数,极大地扩展了XPath在字符串处理上的能力。这意味着在支持XPath 2.0及更高版本的环境中,你可以根据实际需求,灵活选择
    substring()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    或正则表达式。

总结来说:

如果你面对的是结构化、位置固定、长度可预测的字符串,或者只需要基于简单的分隔符进行截取,那么

substring()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
是你的首选,它足够简单高效。

但如果你的字符串是半结构化、模式复杂、长度可变,或者需要进行复杂的校验和提取,那么正则表达式的强大功能就显得不可或缺了。在XPath 2.0+的环境下,这两种工具可以相辅相成,共同解决更广泛的字符串处理问题。我的看法是,没有绝对的好坏,只有是否适合当前任务。能用简单的方法解决,就别把问题复杂化;但遇到复杂问题,也别害怕引入更强大的工具。

以上就是XPath的substring()函数如何提取子字符串?的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号