这次的更新主要引入了支持正则表达式的全文检索、批量替换和调试模式。
正则表达式
我一直觉得原来的全文检索有一个遗憾,虽然可以通过多个关键词实现较为精确的查询,但还是不如正则表达式灵活和精确。
这是个蓄谋已久的需求,但直到真正做起来,才发现很多有意思的东西。虽然SQLite3提供支持正则表达式查询的“REGEX”关键词,但并没有实际实现这个功能,而是需要写程序实现并在数据库接口中注册这个函数:
```python import sqlite3 conn = sqlite3.connect('/tmp/your-database-file.db') # 使用正则表达式匹配给定内容的函数,返回布尔类型 def regexp_search(expr, item): """Check if the item has a sub-string which matches the expr""" reg = re.compile(expr) return reg.search(item) is not None # 在数据库中注册这个函数 conn.create_function('REGEXP', 2, regexp_search) cur = conn.execute('select id,title from post where content REGEXP ?', '\babc\b') row = cur.fetchone() print row conn.close() ```在SQLAlchemy中具体的实现方式是:
```python # 注册函数 dbe = sqlalchemy.create_engine("sqlite:///tmp/your-database-file.db") conn = dbe.connect() conn.connection.create_function('REGEXP', 2, regexp_search) # 在SQL Expression Language中创建查询条件 tbl = Post.__table__ cond_1 = tbl.c.title.op('regexp')(r'\babc\b') cond_2 = tbl.c.content.op('regexp')(r'\babc\b') ```和普通的全文检索一样,正则表达式的全文检索也支持使用多个表达式作为查询条件,多个条件之间是与的关系。现在可以这样查询所有包含“UltraBlog.vim”但不把推广代码算在内的文章了:
```vim :UBRegexSearch [^\[]UltraBlog\.vim[^\]] ```批量替换
在我换过新域名后,我就觉得这个功能很有必要了:
```vim :UBReplace https://sinolog.it https://0x3f.org ```包含第一个参数内容并被替换的文章数目会显示在Vim的命令输出缓冲区中。
有了前面实现全文检索支持正则表达式的尝试,再实现支持正则表达式的批量替换就容易多了:
```python # 转换字符串成raw格式的函数 def raw(text): """Returns a raw string representation of text""" escape_dict={'\a':r'\a', '\b':r'\b', '\c':r'\c', '\f':r'\f', '\n':r'\n', '\r':r'\r', '\t':r'\t', '\v':r'\v', '\'':r'\'', '\"':r'\"', '\0':r'\0', '\1':r'\1', '\2':r'\2', '\3':r'\3', '\4':r'\4', '\5':r'\5', '\6':r'\6', '\7':r'\7', '\8':r'\8', '\9':r'\9'} return "".join([escape_dict.get(char,char) for char in text]) # 使用正则表达式替换字符串的函数 def regex_replace(string, expr, repl): """Do substitutions on the string for repls matching the expr""" r = re.compile(raw(expr)) return r.sub(repl, string) # 在数据库中注册这个函数 conn.connection.create_function('regex_replace', 3, regex_replace) # 在SQL语句中使用这个函数 sql_replace = "update post set title=regex_replace(title,:needle,:replacement),content=regex_replace(content,:needle,:replacement)" conn.execute(sql_replace, {'needle':r'\babc\b', 'replacement':'xyz'}) ```最终,这个命令是这样的:
```vim :UBRegexReplace \babc\b xyz ```实现批量替换容易,但要解决由此引出的一个问题就费周折了,就是批量替换过文章内容后怎样和博客同步的问题,现在我还没有好的想法,留作以后实现。
调试模式
开启调试模式可以将所有被执行的SQL语句显示在Vim的命令输出缓冲区中,在有异常抛出时,也可以显示堆栈信息。由于开启调试模式既不需要修改代码,也不需要重启Vim,这可以极大地方便开发时对UltraBlog.vim的调试,也能使用户提交问题时能反馈更多更详细的信息。
以下三个命令用于控制调试模式的开启状态:
:UBEnableDebug
:UBDisableDebug
:UBToggleDebug
其它内容
本次更新的内容如下:
- Feature: Add the command :UBRegexSearch, doing full-text searches with regular expressions !
- Feature: Add the command :UBReplace, doing full-text substitutions.
- Feature: Add the command :UBRegexReplace, doing full-text substitutions with regular expressions.
- Feature: Add commands :UBEnableDebug, :UBDisableDebug, :UBToggleDebug and an option ub_debug. In debug mode, SQL statements and stack traces of exceptions will be displayed.
- Change: Undo keywords highlighting after executing :UBList.
- Bugfix: Exceptions raised when opening the current item under cursor in item lists if the option ub_hotkey_save_current_item has not been set. Now this options comes with a default value.
关于UB的详细信息在这里。
Posted via UltraBlog.vim.