简体   繁体   English

Javascript-使用string.replace替换文本的函数

[英]Javascript- Use function for string.replace replacement text

I'm attempting to replace url's in a string by calling a function that shortens the url's and then replaces the text. 我试图通过调用缩短网址的函数来替换字符串中的url,然后替换文本。 The shortening logic works perfectly, and I end up with the proper replacement url, however i cannot get the replace function to work correctly. 缩短逻辑工作得很好,我最终得到了正确的替换URL,但是我无法使替换功能正常工作。 Here is my code. 这是我的代码。

var newtext = shortenUrl(curText);

var shortenUrl = function (text) {
    var exp = /(ftp|http|https):\/\/(?!bit\.ly)(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ig;

    text.replace(exp, 
                 function ($1) {
                      $.getJSON("http://api.bitly.com/v3/shorten?login=xxxxxx&apiKey=xxxx&longUrl=" + escape($1) + "&format=json", 
                                function (result) {
                                    return result.data.url;
                                });
                 });
    return text;
};

result.data.url contains a proper shortened url per the bit.ly API specs; result.data.url包含每个bit.ly API规范的适当缩短的url; however, newtext is always null for some reason. 但是,由于某种原因, newtext始终为null。

  1. text.Replace will not change the contents of text => you need to say text = text.Replace(...) because strings in javascript are immutable ( https://stackoverflow.com/q/51193/4572 for more info) text.Replace不会改变text =>你需要说text = text.Replace(...)因为javascript中的字符串是不可变的( https://stackoverflow.com/q/51193/4572了解更多信息)

  2. getJSON is performed asynchronously meaning that execution of the function that you feed to replace will start the JSON call but doesn't wait for the JSON call to finish , you need to use $.ajax instead with the async option turned off (see the code below, as well as this link: Is it possible to set async:false to $.getJSON call ) getJSON是异步执行的,这意味着您要替换的函数的执行将启动JSON调用但不等待JSON调用完成,您需要使用$ .ajax而不关闭async选项(请参阅代码下面,以及这个链接: 是否可以设置async:false到$ .getJSON调用

  3. Because the JSON call merely executes a callback (ie function(result)) it doesn't actually return a value so you need to create what is called a "closure" in order to get state (result.data.url) from inside your function(result) call to the parent scope (in this case the scope created by function($1)). 因为JSON调用只是执行一个回调(即函数(结果)),所以它实际上并不返回一个值,所以你需要创建一个所谓的“闭包”,以便从你的内部获取状态(result.data.url) function(result)调用父作用域(在本例中是函数($ 1)创建的作用域)。 Closures can get very confusing, especially in javascript, sometimes yielding non-obvious results. 闭包可能会变得非常混乱,尤其是在javascript中,有时会产生非显而易见的结果。 Thankfully this is a simple closure. 谢天谢地,这是一个简单的闭包。 For a little more info you can checkout this https://stackoverflow.com/q/7363168/4572 , or the google. 有关更多信息,您可以查看此https://stackoverflow.com/q/7363168/4572或谷歌。

Here is the code that works correctly for me: 这是适合我的代码:

var shortenUrl = function (text) {
    var exp = /(ftp|http|https):\/\/(?!bit\.ly)(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ig;

    text = text.replace(exp, function ($1) {
       var newUrl = "";
       $.ajax({
           url: "http://api.bitly.com/v3/shorten?login=xxxxx&apiKey=xxxxxx&longUrl=" + escape($1) + "&format=json",
           dataType: 'json',
           async: false,
            success: function(result) {
                newUrl = result.data.url
            }
        });
        return newUrl;
    });
    return text;
};

As the functions you are calling are not synchronous you will need some sort of callback function. 由于您调用的函数不是同步的,因此您需要某种回调函数。 The following code should do the trick: 以下代码应该可以解决问题:

var newtext;
shortenUrl(curText, function(url) {
  newtext = url;
});

var shortenUrl = function (text, callback) {
    var exp = /(ftp|http|https):\/\/(?!bit\.ly)(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ig;

    text = text.replace(exp, 
             function ($1) {
                  $.getJSON("http://api.bitly.com/v3/shorten?login=xxxxxx&apiKey=xxxx&longUrl=" + escape($1) + "&format=json", 
                            function (result) {
                                return result.data.url;
                            });
             });
    callback(text);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM