kylin

醉里论道,醒时折花。

kylin

RegExp对象踩坑记录

gtest()

现象

g的正则对象多次调用test()结果不同

1
2
3
4
5
var reg = new RegExp('51-(.*)','g')
reg.test('51-in')
// true
reg.test('51-in')
// false

原因

每个RegExp对象都包含5个属性。属性source是一个只读的字符串,包含正则表达式的文本。属性global是一个只读的布尔值,用以说明这个正则表达式是否带有修饰符g。属性ignoreCase也是一个只读的布尔值,用以说明正则表达式是否带有修饰符i,属性multiline是一个只读布尔值,用以说明正则表达式是都带有修饰符m。最后一个属性lastIndex,它是一个可读/写的整数。如果匹配模式带有g修饰符,这个属性存储在整个字符串中下一次检索的开始位置,这个属性会被exec()和test()方法用到。

1
2
3
4
5
6
7
8
9
var reg = new RegExp('51-(.*)','g')
reg.test('51-in')
// true
reg.lastIndex
// 5
reg.test('51-in')
// false
reg.lastIndex
// 0

解决姿势

与exec()和test()不同,String方法search()、replace()、match()并不会用到lastIndex属性。实际上,String方法只是简单地将lastIndex属性值重置为0。如果让一个带有修饰符g的正则表达式对多个字符串执行exec()或test(),要么在每个字符串中找出所有的匹配以便将lastIndex自动重置为0,要么显式将lastIndex手动设置为0(当最后一次检索失败时需要手动设置lastIndex)。如果忘了手动设置lastIndex的值,那么下一次对新字符串进行检索时,执行检索的起始位置可能就不是字符串的开始位置,而可能是任意位置。当然,如果RegExp不带修饰符g,则不必担心会发生这种情况。同样要记住,在ECMAScript5中,正则表达式直接量每次计算都会创建一个新的RegExp对象,每个新RegExp对象具有各自的lastIndex属性,这势必会大大减少“残留”lastIndex对程序造成的意外影响。

根据以上说明,可是采用一下几种替换方式

  • test()方法不使用g
  • 使用正则表达式直接量
  • 每次都重新new RegExp
  • 手动重置lastIndex

node子进程与调度任务

前言

有时候我们会需要在服务端去执行一些命令或者脚本,这时候可以使用nodechild_process模块来新建子进程。

新建子进程

child_process存在几种创建子进程的方法。参考

  • 创建异步进程
    • child_process.exec(command[, options][, callback]) 衍生一个 shell 并在 shell 上运行一个命令,当完成时会传入 stdout 和 stderr 到一个回调。
    • child_process.execFile(file[, args][, options][, callback])child_process.exec() 类似,但它直接衍生命令,且不用先衍生一个 shell。
    • child_process.fork(modulePath[, args][, options])衍生一个新的 Node.js 进程,并通过建立一个允许父进程和子进程之间相互发送信息的 IPC 通讯通道来调用一个指定的模块。
    • child_process.spawn(command[, args][, options])方法会异步地衍生子进程,且不会阻塞 Node.js 的事件循环。
      • options.detached
      • options.stdio
  • 创建同步进程
    • child_process.execFileSync(file[, args][, options])函数则以同步的方式提供了与child_process.execFile()相同的功能,但会阻塞事件循环,直到衍生的子进程退出或终止。
    • child_process.execSync(command[, options])函数则以同步的方式提供了与child_process.exec()相同的功能,但会阻塞事件循环,直到衍生的子进程退出或终止。
    • child_process.spawnSync(command[, args][, options])函数则以同步的方式提供了与child_process.spawn()相同的功能,但会阻塞事件循环,直到衍生的子进程退出或终止。

这里以spawn方法为例。

execspawn放法都可以满足我异步执行命令的需求,但除此之外我还需要实时获取子进程的输出,而exec只能在执行完之后一次获取输出,所以最终选择了spawn

阅读全文

mongodb(mongoose)使用小结

文档结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"origin":{
"home_name":"伯乐在线",
"home":"http://web.jobbole.com/",
"link":"http://web.jobbole.com/90719/",
"id":"90719"
},
"uid":8140,
"title":"我理解中的“大前端”/“大无线”",
"article_info":{
"content":'<div class="entry">↵↵ ↵ <div>↵...'
"categorys":["基础技术"],
"copyright":{
"link":"http://f2e.souche.com/blog/da-qian-duan-wo-de-li-jie/",
"name":"大搜车无线团队"
},
"tags":["前端"],
"post_date":1489161600,
"is_filtered":false,
"is_unique":false
},
"insert_time":1489750591.488951
}

根据某字段查询

根据uid字段查询

1
Article.find({'uid':2})

根据orgin对象中的home字段查询,使用.操作符

1
Article.find({'origin.home':'http://web.jobbole.com/'})

指定输出文档显示的字段

前端渲染列表时,查询如示例文档这样的带有大段html文本的数据会比较慢,这时可以将UI渲染用不到的字段过滤

1
2
Article.find({'uid':2},{_id: 0, 'article_info.content': 0})
// 不输出_id与article_info下的content字段 0表示删除 1表示保留

阅读全文

使用mongo shell命令行工具在指定数据库下新建用户

在指定数据库下新建用户

输入mongo命令

1
2
3
4
5
root@iZm5e3ljqlvdsruj2dkr7pZ:~# mongo
MongoDB shell version v3.4.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.2
>

先在admin数据库完成校验

1
2
3
4
> use admin
switched to db admin
> db.auth('xx','xxx')
1

切换到想要新建用户的数据库

1
2
> use test
switched to db test

使用db.createUser()新建用户,参考文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> db.createUser({
... ... user:"root",
... ... pwd:"root",
... ... roles:[{
... ... role:'readWrite',db:'test'
... ... }]
... ... })
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "readWrite",
"db" : "test"
}
]
}

计算笛卡尔积

计算笛卡尔积

1
2
3
4
5
6
7
8
9
10
11
function cartesianProductOf() {
return Array.prototype.reduce.call(arguments, function(a, b) {
var ret = [];
a.forEach(function(a) {
b.forEach(function(b) {
ret.push(a.concat([b]));
});
});
return ret;
}, [[]]);
}

使用方法

1
cartesianProductOf(['1','3'],['a','b'])

python折腾过程中遇到的坑全纪录

Scrapy的依赖库Six与系统依赖库Six发生了冲突

这应该是一个mac

error

1
2
3
DEPRECATION: Uninstalling a distutils installed project (six) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
Uninstalling six-1.4.1:
...

解决方法

参考starkoverflow

  • 使用virtualenv创建一个隔离的python环境
  • 使用--ignore-installed命令
1
sudo pip install libName --upgrade --ignore-installed six

Scrapy命令使用时报错

error

1
ImportError: cannot import name xmlrpc_client

这应该是一个mac

方法一:重装six

1
sudo rm -rf /Library/Python/2.7/site-packages/six*
1
sudo rm -rf /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six*

阅读全文

python学习笔记(二)

range()函数

range(n)函数可以生成一个0~n-1整数序列

1
2
>>> range(5)
[0, 1, 2, 3, 4]

类型转换

string 转 int——int()

1
birth = int(raw_input('birth: '))

dict

dict与js中的Object相似,不同的是不能像js一样用.运算符读取

1
2
3
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

判断key是否存在

  • in

    1
    2
    >>> 'Thomas' in d
    False
  • get()

第二个参数可以指定不存在时返回的值

1
2
3
>>> d.get('Thomas')
>>> d.get('Thomas', -1)
-1

删除并返回指定元素

1
2
3
4
>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}

阅读全文

python学习笔记(一)

编码问题

在编写Python时,当使用中文输出或注释时运行脚本,会提示错误信息:

原因:

python的默认编码文件是用的ASCII码,而编辑器讲文件存成了UTF-8

解决方案:

在文件第一行添加以下代码

1
# -*- coding: UTF-8 -*-

或者

1
#coding=utf-8

字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
print r'\\\t\\\ '
# r''表示''内部字符默认不转义
# 如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许在交互式命令行中用'''...'''
# 如 >>> print '''line1
# ... line2
# ... line3'''
# 的格式表示多行内容,若写成程序则如下:
print '''line1
line2
line3'''
# r''还能与'''...'''结合如下:
print r'''\nline1
line2
line3'''

阅读全文

TravisCI自动化构建与Karma测试实践记录

Karma

安装的依赖

1
2
$ npm install karma --save-dev
$ npm install karma-jasmine karma-chrome-launcher jasmine-core --save-dev

装完依赖后可以用以下命令运行测试

1
2
# Run Karma:
$ ./node_modules/karma/bin/karma start

若觉得./node_modules/karma/bin/karma的写法太长,则可以全局安装karma-cli

1
npm install -g karma-cli

初始化配置

最简单的方法是使用命令karma init来创建配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ karma init
Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine
Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no
Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> Chrome
>
What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
>
Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>
Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes
Config file generated at "/Users/xx/Documents/Himmas/melody/karma.conf.js".

阅读全文