Jquery:用多个下拉框替换html标签之外的所有未格式化文本

时间:2016-09-21 20:13:09

标签: javascript html regex drop-down-menu replace

我希望在字符串中找到一个子字符串(来自数组),然后用一个下拉框替换它,该下拉框的标题将等于子字符串。

字符串来自用户输入,子字符串是从我的工作代码中的数据库中提取的。

我从DavidTonarini在这个问题中给出的答案开始工作:Javascript: replace() all but only outside html tags

但是,这只排除'<'之间包含的文字。和'<'。

我还使用了jconder对这个问题的回答。这部分解决了这个问题。

如果您在所包含的工作小提琴中输入:'a level a level',那么您将看到'a levels'作为下拉框返回,但'level'以纯文本形式返回,但是它应该是与其在数组中的条目匹配,并替换为下拉框。在用户输入中重复相同的字符串时也会出现问题。我希望能够在用户输入中多次匹配相同的子字符串。

var data = {
  "a_levels": {
    "a_level": {
      id: 1,
      units: 2,
      created: "2016-10-04 19:00:05",
      updated: "2016-10-05 09:37:46"
    },
    "a_levels": {
      id: 2,
      units: 2,
      created: "2016-10-05 08:19:27",
      updated: "2016-10-05 09:37:39"
    }
  },
  "a_level": {
    "a_level": {
      id: 1,
      units: 2,
      created: "2016-10-04 19:00:05",
      updated: "2016-10-05 09:37:46"
    },
    "a_levels": {
      id: 2,
      units: 2,
      created: "2016-10-05 08:19:27",
      updated: "2016-10-05 09:37:39"
    }
  }
};
var input, // Create empty variables.
  response;

$('#submit').click(function() {
  input = $('#userInput').val();
  response = input;
  // CREATE DROPDOWN BOXES.
  var strings_used = [];
  $.each(data, function(i, v) { // Iterate over first level of output.

    for (var itr = 0; itr < strings_used.length; ++itr) {
      if (strings_used[itr].indexOf(i) !== -1) {
        return true;
      }
    }
    var searchWord = i.replace(/_/g, " "); // Replace underscores in matches with blank spaces.
    var regEx = new RegExp("(" + searchWord + ")(?!([^<]+)?>)", "gi"); // Create regular expression which searches only for matches found outside html tags.
    var tmp = response.replace(regEx, "<span class='btn-group'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>" + searchWord + "<span class='caret'></span></button><ul class='" + i + " dropdown-menu'></ul></span>"); // Replace matching substrings with dropdown boxes.
    if (tmp !== response) { // Check if replacement is complete.
      response = tmp; // Update response.
      strings_used.push(i);
    }
  });
  $('#template').empty().append(response); // Populate template container with completed question response including dropdown boxes.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>

  <div id="searchbox">
    <div class="input-group">
      <input id="userInput" type="text" class="form-control" placeholder="type here...">
      <span id="submit" class="input-group-btn">
			  <button class="btn btn-default" type="submit">GO!</button>
			</span>
    </div>
  </div>

  <div class="row">
    <div id="template" class="col-sm-10 col-md-offset-1 text-left"></div>
  </div>

</body>

1 个答案:

答案 0 :(得分:1)

如果我现在理解正确,你希望它在第一次替换后停止迭代字典。在这种情况下,这应该工作:

abstract public class Item
{
    public abstract byte getIndex();
}

public class Depot extends Item
{
    public static final byte INDEX = 18;

    public byte getIndex()
    {
        return INDEX;
    }
}

public class Train extends Item
{
    public static final byte INDEX = 12;

    public byte getIndex()
    {
        return INDEX;
    }
}

public class Road extends Item
{
    public static final byte INDEX = 6;

    public byte getIndex()
    {
        return INDEX;
    }
}

通过检查正则表达式是否修改了字符串,您可以检测是否进行了替换,然后通过var output = ['the_car_was_found_abandoned_in_a_nearby_town', 'found_abandoned']; var template = 'the car was found abandoned in a nearby town'; $.each(output, function(i,v){ var searchWord = v.replace(/_/g, " "); var regEx = new RegExp("("+searchWord+")(?!([^<]+)?>)", "gi"); var tmp = template.replace(regEx, "<span class='btn-group'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>"+searchWord+"<span class='caret'></span></button><ul id='"+i+"' class='dropdown-menu'></ul></span>"); if (tmp !== template) { template = tmp; console.log(template); return false; } }); 来自returning false;回调,您可以提前结束迭代。

虽然我不确定这是否是整张图片,如果您只想让它跳过字典中的其他条目,这些条目是更长,更合适的匹配的子串,那么您需要订购字典的方式略有不同,例如:

$.each()

如果您按这种方式订购字典,那么您可以运行上述算法:

var dict = {
    "the_car_was_found_abandoned_in_a_nearby_town":
      ["the_car_was_found_abandoned_in_a_nearby_town", "found_abandoned"],
    "some_other_text_that_isn't_a_substring_of_another_entry:
      ["some_other_text_that_isn't_a_substring_of_another_entry", "of_another_entry", "some_other"]
};

以上将输出:

var dict = {
    "the_car_was_found_abandoned_in_a_nearby_town":
      ["the_car_was_found_abandoned_in_a_nearby_town", "found_abandoned"],
    "some_other_text_that_isn't_a_substring_of_another_entry:
      ["some_other_text_that_isn't_a_substring_of_another_entry", "of_another_entry", "some_other"]
};
var template = 'the car was found abandoned in a nearby town with some other junk';

Object.keys(dict).forEach(function(d) {
  $.each(dict[d], function(i,v) {
    var searchWord = v.replace(/_/g, " ");
    var regEx = new RegExp("("+searchWord+")(?!([^<]+)?>)", "gi");

    var tmp = template.replace(regEx, "<span class='btn-group'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>"+searchWord+"<span class='caret'></span></button><ul id='"+i+"' class='dropdown-menu'></ul></span>");
    if (tmp !== template) {
      template = tmp;
      console.log(template);
      return false;
    }
  });
});

另一种不需要预先排序字典输入的方法是维护已使用输入的列表,并检查剩余输入是否都是已使用的输入的子串,应该具有相同的输入结束效果:

"<span class='btn-group'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>the car was found abandoned in a nearby town<span class='caret'></span></button><ul id='0' class='dropdown-menu'></ul></span> with some other junk"
"<span class='btn-group'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>the car was found abandoned in a nearby town<span class='caret'></span></button><ul id='0' class='dropdown-menu'></ul></span> with <span class='btn-group'><button class='btn btn-primary dropdown-toggle' type='button' data-toggle='dropdown'>some other<span class='caret'></span></button><ul id='2' class='dropdown-menu'></ul></span> junk"