确定path是否是Node.js中另一个path的子目录
我正在为我想为其中有一个事件侦听器的每个父目录发出事件的MQTT处理程序 。 例如:
如果有以下MQTTpath可用,那里有下标 – 有这些path的事件监听器 –
test
-
replyer/request
-
test/replyer/request
而有人在主题test/replyer/request/@issuer
,应该有2个事件: test
, test/replyer/request
。
鉴于任何path都是可能的,并没有可用的有效事件列表,我们必须检查path是否是另一个父path。 我们可以用正则expression式吗? 如果是这样,它会是什么样子? 有更简单/更有效的解决scheme吗?
使用indexOf就足够了。
function isParentOf(parent, dir) { return dir.indexOf(parent) === 0; } isParentOf('test/replyer/request/@issuer', 'test') // true isParentOf('test/replyer/request/@issuer', 'replyer/request') // false isParentOf('test/replyer/request/@issuer', 'test/replyer/request') // true
请忽略接受的答案。 它不能以任何身份工作。 从来没有,永远不会。
2017年末答案
在ES6中。
const isChildOf = (child, parent) => { if (child === parent) return false const parentTokens = parent.split('/').filter(i => i.length) return parentTokens.every((t, i) => child.split('/')[i] === t) }
如果您正在使用node.js,并且想要跨平台,请包含path
模块,并用split(path.sep)
replacesplit('/')
split(path.sep)
。
怎么运行的:
所以,你想知道一个目录(比如home/etc/subdirectory
)是否是另一个目录的子目录(比如home/etc
)。
它采用假设的child
path和parent
path,并使用split
将它们转换为数组:
['home', 'etc', 'subdirectory'], ['home', 'etc']
然后遍历parent
数组中的所有令牌,并使用ES6的.every()
对它们在child
数组中的相对位置逐一进行检查。
如果父母的一切都与孩子的一切相符,知道我们已经排除他们完全相同的目录(使用child !== parent
),我们将得到我们的答案。
让节点本身做的工作。
const path = require('path'); const relative = path.relative(parent, dir); return !!relative && !relative.startsWith('..') && !path.isAbsolute(relative);
它也为你做标准化。
const path = require('path'); const tests = [ ['/foo', '/foo'], ['/foo', '/bar'], ['/foo', '/foobar'], ['/foo', '/foo/bar'], ['/foo', '/foo/../bar'], ['/foo', '/foo/./bar'], ['/bar/../foo', '/foo/bar'], ['/foo', './bar'], ['C:\\Foo', 'C:\\Foo\\Bar'], ['C:\\Foo', 'C:\\Bar'], ['C:\\Foo', 'D:\\Foo\\Bar'], ]; tests.forEach(([parent, dir]) => { const relative = path.relative(parent, dir); const isSubdir = !!relative && !relative.startsWith('..') && !path.isAbsolute(relative); console.log(`[${parent}, ${dir}] => ${isSubdir} (${relative})`); });
也可以跨驱动器在Windows上运行。
[/foo, /foo] => false () [/foo, /bar] => false (..\bar) [/foo, /foobar] => false (..\foobar) [/foo, /foo/bar] => true (bar) [/foo, /foo/../bar] => false (..\bar) [/foo, /foo/./bar] => true (bar) [/bar/../foo, /foo/bar] => true (bar) [/foo, ./bar] => false (..\Users\kozhevnikov\Desktop\bar) [C:\Foo, C:\Foo\Bar] => true (Bar) [C:\Foo, C:\Bar] => false (..\Bar) [C:\Foo, D:\Foo\Bar] => false (D:\Foo\Bar)
用正则expression式来做是一种方法(对于每个有事件监听器的path,检查发布的主题是否以该path开始),但是因为更有可能你会有很多不同的path,比你长得荒谬url,打破发表的话题可能会更有效率。
像这样的东西可能更容易阅读:
编辑 : @huaoguo是绝对正确的,indexOf === 0是我们真正需要的!
let paths = [ 'test', 'replyer/request', 'test/replyer/request' ] let topic = 'test/replyer/request/@issuer' let respondingPaths = (paths, topic) => paths.filter(path => topic.indexOf(path) === 0) console.log(respondingPaths(paths, topic)) // ['test', 'test/replyer/request']
- 使用JavaScript(node.js)“反向”正则expression式
- 使用NODE.js的dynamic网页/ WebApp
- Node Express中caching:白名单/黑名单视图如何?
- 如何在一个节点上使用requirejs,jquery和d3 express webserver
- 简单Nodejs正则expression式:从两个string之间提取文本
- Node.js / Express中session_start()和$ _SESSION的等价物
- 为什么受影响的行在更新/删除成功时返回0?
- 生产应用程序中的Console.log使用node.js,express和PM2
- 如何控制node.js&express 3.0服务器上的file upload