【问题标题】:JavaScript regex to get a list of variables in a string starting with the @ characterJavaScript正则表达式获取以@字符开头的字符串中的变量列表
【发布时间】:2016-02-29 21:22:03
【问题描述】:

我需要在字符串中提取变量数组。字符串如下所示:

select * from properties where city = @city and state = @state and price = @price

我需要这样的数组中的结果:

['city', 'state', 'price']

我尝试了很多正则表达式,但没有好的结果,我无法在 StackOverflow 或 Google 上找到类似的问题。这甚至可能吗?如何提取这些以@开头的变量?

【问题讨论】:

  • 使用@(\w)* 捕获第一组,即\1
  • .split() 结合 .filter() 怎么样?
  • 感谢大家迄今为止的出色帮助!很好奇为什么投反对票... :(
  • ▼ 因为你没有做作业。不过不是我。
  • 但这不是真的@noob,我知道不是你。谢谢你的建议。

标签: javascript arrays regex string


【解决方案1】:
var x="@city @state @price"
x.match(/(^|\s)@(\w+)/g).map(function(v){return v.trim().substring(1);})

这行得通,输出是:

[“城市”、“州”、“价格”]

【讨论】:

  • 这太棒了! +1
【解决方案2】:

我记得使用以下正则表达式模式从 SQL 查询中提取参数名称。这应该考虑 SQL 中的参数命名规则和查询中的换行符:

(^|\W)@([A-Za-z]+\w*)(?=$|\W)

在 regex101 上测试:https://regex101.com/r/oH0gI2/1

另外,我建议不要将正则表达式与拆分、地图和其他普通 JS 混合使用。 用一种工具更好地解决问题。

【讨论】:

  • 这太棒了阿图尔!我想我可能用错了。我做了类似query.match(/(^|\W)@([A-Za-z]+\w*)(?=$|\W)/g); 的事情,但输出就像:[" @city", " @state", " @price"]。比如如何去掉前导空格和@符号?
  • 那是因为匹配被分成 3 个捕获组。您必须专门访问第三组。 jsfiddle.net/ta27xfjb/3
【解决方案3】:

split将字符串分解成单词

var words = string.split(' ');

然后filter 使用字符串starts_with 方法的单词数组。要获取紧跟在@ 之后的字符,可以使用string.slice 方法并传递1 作为参数,从第二个字符开始获取字符串。

var button = document.getElementById("my-button");
var result = document.getElementById("result");

button.addEventListener("click", function() {
  var query = prompt("Enter your query");
  var words = query.split(" ");
  
  var specificWords = words.filter(function(word) {
        return word.startsWith("@");
    }).map(function(word) {
        return word.slice(1)
    });
  
  result.innerHTML = "[" + specificWords + "]";

});
<p>Paste the following code</p>
<p id="query">select * from properties where city = @city and state = @state and price = @price</p>

<button id="my-button">Find Words</button>

<p id="result"></p>

这会回馈

['city', 'state', 'price'];

【讨论】:

  • split()slice() 在这种情况下获胜。
  • 注意:链接 .filter().map() 将不必要地循环数组两次。
  • 我确实添加了一个示例。你们应该玩它
  • @SébastienVercammen 我确实尝试将它们都添加到过滤器函数中,但出现错误。我必须把它们拴起来才能完成这项工作
  • @RichardHamilton 问题是它们不能合并。 filter() 是过滤元素,map() 是对每个元素应用一个过程并返回一组结果——它们都是用来做不同的事情的。对于最优的版本,他需要在调用split()之后为数组做自己的循环。
【解决方案4】:

很多可能的方法来解决这个问题。

  • 使用正则表达式:

    /@(\w+)/g
    
  • 使用.split().filter()

    var foo = 'The @quick brown @fox jumps over the @lazy @dog';
    
    foo.split(' ').filter(function(x) {
      return (x.indexOf('@') > -1);
    });
    

注意:我没有使用.map() 删除@,因为这会不必要地循环数组两次(一次用于过滤,一次用于映射)。

为了获得最佳性能,您需要自己循环数组:

var foo = 'The @quick brown @fox jumps over the @lazy @dog';
var bar = foo.split(' ');
var result = [];

for (var i = 0; i < bar.length; i++) {
  if (bar[i].indexOf('@') > -1) {
    result.push(bar[i].slice(1));
  }
}

document.write(result);

【讨论】:

  • 这包括“@”,他想要的输出不包括它。
  • 不链接.filter() 并为数组中的元素创建自己的循环非常容易。这是一个展示如何解决问题的示例。
  • 是否可以仅使用正则表达式删除最终正则表达式输出中的“@”? j/w
  • @myoplabo 是的,@ 在我的示例中位于捕获组之外。
猜你喜欢
  • 1970-01-01
  • 2010-10-28
  • 2014-10-28
  • 2011-09-16
  • 2015-05-14
  • 2021-11-04
  • 1970-01-01
  • 2017-03-16
相关资源
最近更新 更多