首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何扩展EJSON以序列化RegEx以实现交互?

如何扩展EJSON以序列化RegEx以实现交互?
EN

Stack Overflow用户
提问于 2016-02-22 09:00:25
回答 2查看 281关注 0票数 2

在我的Meteor应用程序中,我有一个任意的(E)JSON,它被创建并通过连接从客户端发送到服务器。它使用RegExp对象对结果进行归零:

代码语言:javascript
复制
# on the client
selector = 
  "roles.user": { "$ne": null } 
  "profile.email": /^admin@/gi 

在客户端,一切都很好,但是如果我通过Meteor.callMeteor.subscribe将其传递给服务器,则生成的(E)JSON采用以下形式:

代码语言:javascript
复制
# on the server
selector =
  "roles.user": { "$ne": null }
  "profile.email": {}

...and在某个地方,一个工程师在里面死了一点。

网络上有大量的资源解释为什么RegEx不能通过JSON.stringify/JSON.parse或等效的EJSON方法序列化。

我并不认为RegEx序列化是不可能的。那么如何才能做到呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-22 09:00:25

在回顾这个HowToMeteor文档之后,我们可以使用EJSON.addType方法序列化RegEx。

扩展RegExp -向RegExp提供EJSON.addType实现所需的方法。

代码语言:javascript
复制
RegExp::options = ->
  opts = []
  opts.push 'g' if @global
  opts.push 'i' if @ignoreCase
  opts.push 'm' if @multiline
  return opts.join('')

RegExp::clone = ->
  self = @
  return new RegExp(self.source, self.options())

RegExp::equals = (other) ->
  self = @
  if other isnt instanceOf RegExp
    return false
  return EJSON.stringify(self) is EJSON.stringify(other)

RegExp::typeName = ->
  return "RegExp"

RegExp::toJSONValue = ->
  self = @
  return {
    'regex': self.source
    'options': self.options()
  }

给EJSON.addType打电话--在任何地方都这样做。不过,最好将其提供给客户端和服务器。这将反序列化上面toJSONValue中定义的对象。

代码语言:javascript
复制
EJSON.addType "RegExp", (value) ->
  return new RegExp(value['regex'], value['options'])

测试在您的控制台-不要相信我的话。你自己看吧。

代码语言:javascript
复制
> o = EJSON.stringify(/^Mooo/ig)
"{"$type":"RegExp","$value":{"regex":"^Mooo","options":"ig"}}"
> EJSON.parse(o)
/^Mooo/gi

在这里,您可以在客户端和服务器上序列化和解析一个RegExp,可以通过线路传入、保存在会话中,甚至可能存储在查询集合中!

编辑添加IE10+错误:在严格模式下不允许为只读属性分配注释中@ the的礼貌

代码语言:javascript
复制
import { EJSON } from 'meteor/ejson';

function getOptions(self) {
  const opts = [];
  if (self.global) opts.push('g');
  if (self.ignoreCase) opts.push('i');
  if (self.multiline) opts.push('m');
  return opts.join('');
}

RegExp.prototype.clone = function clone() {
  return new RegExp(this.source, getOptions(this));
};

RegExp.prototype.equals = function equals(other) {
  if (!(other instanceof RegExp)) return false;
  return EJSON.stringify(this) === EJSON.stringify(other);
};

RegExp.prototype.typeName = function typeName() {
  return 'RegExp';
};

RegExp.prototype.toJSONValue = function toJSONValue() {
  return { regex: this.source, options: getOptions(this) };
};

EJSON.addType('RegExp', value => new RegExp(value.regex, value.options));
票数 7
EN

Stack Overflow用户

发布于 2017-04-12 09:00:47

有一个简单得多的解决方案:通过RegExp将.toString()压缩,将其发送到服务器,然后将其解析为RegExp。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35549468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档