如何更有效地重写大量文本?

时间:2019-05-20 23:13:58

标签: javascript jquery

在这里使用CMS,因此源代码无法使用。有问题的页面是一个巨大的时间表列表。

<div class="body-time">8:00 pm - 9:00 pm</div>

现在想象一下,但是有几十个(如果不是数百个)条目。

问题在于,我们从中提取数据的Feed中的时间设置为UTC时间。我们的活动所在的时区需要倒退五个小时。

问题

我需要对文本元素进行大量重写。

我能想到的最好的事情就是找到并替换这样的文本:

$(".body-time").text(function () {
    return $(this).text().replace('8:00 pm', '9:00 pm');
});

$(".body-time").text(function () {
    return $(this).text().replace('9:00 pm', '10:00 pm');
});

但是,如果我每次输入必须以30分钟为间隔来重写文本,那么这在页面上将是多余且繁琐的。

有没有一种方法可以更有效地重写文本?大量查找和替换?一切都需要-5小时。

2 个答案:

答案 0 :(得分:3)

我不确定查找和替换数百个元素的效率如何。

正如评论者所说,在将时间写入页面之前,解决问题可能对您更有益。无论如何,仍然可以以更有效的方式完成您要问的事情。

首先,您应该注意,您只需要一个选择器函数,因为jquery会将其应用于与该类匹配的所有元素。 从那里,您只需要将时间转换为-5小时即可。诸如momentjs之类的库在这里可能很有用,但是在这里,我将向您展示一种无需额外插件即可实现的方法。

首先,您将split the string移至" - "字符的一半,以提取两次。

从那里可以为每个时间字符串使用regular expressionstring matching提取小时,分钟和一天中的时间。然后,只需从小时数中减去5,然后相应地调整一天中的时间即可。然后把绳子放回去。在下面的示例中,我只是使用了template literal

最后使用" - "重新加入字符串。

$(".body-time").text(function () {
  const timeStr = $(this).text()
  const times = timeStr.split(" - ")
  // you could use momentjs for this next part if you like
  const newTimeStr = times.map(time => {
    let [, hour, minutes, m] = time.match(/(\d):(\d{2}) ([ap]m)/)
    hour = (parseInt(hour) - 5) // subtract 5 hours
    if(hour <= 0){
      m = m === 'pm' ? 'am' : 'pm'
      hour += 12
    }
    return `${hour}:${minutes} ${m}`
  }).join(" - ")
  $(this).text(newTimeStr)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="body-time">1:00 pm - 2:00 pm</div>
<div class="body-time">2:00 am - 3:00 pm</div>
<div class="body-time">3:00 pm - 4:00 am</div>
<div class="body-time">6:00 am - 7:00 am</div>

不需要编写一整页的j​​query选择器。您可能还希望根据其他要求或实际页面的结构与问题不同来修改此算法,但是我希望这可以帮助您了解如何优化方法的要旨。

编辑

这是更简洁的版本,仅使用string#replace

$(".body-time").text(function() {
  return $(this).text().replace(/(\d):(\d{2}) ([ap]m)/gi, (full, hour, minutes, am_pm) => {
    hour = (parseInt(hour) - 5) // subtract 5 hours
    if (hour <= 0) {
      am_pm = am_pm === 'pm' ? 'am' : 'pm'
      hour += 12
    }
    return `${hour}:${minutes} ${am_pm}`
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="body-time">1:00 pm - 2:00 pm</div>
<div class="body-time">2:00 am - 3:00 pm</div>
<div class="body-time">3:00 pm - 4:00 am</div>
<div class="body-time">6:00 am - 7:00 am</div>

答案 1 :(得分:1)

您可以将正则表达式与replace-method一起使用。在替换回调中,您必须注意在上午和下午之间切换的时间。但我认为这可能会影响性能。

$(".body-time").each(function(index){
  let textContent = $(this).text();
  let modifiedText = textContent.replace(/(\d*\:\d*) ([\w]*)/gi, function(match, p1, p2, offset, string){
    let time = p1.split(':');
    let hour = parseInt(time[0]);
    let minute = parseInt(time[1]);
    let modifiedHour = (hour + 7) % 12;
    if (modifiedHour < 10) {
      modifiedHour = '0' + modifiedHour;
    }
    if (minute < 10) {
      minute = '0' + minute;
    }
    let am_pm = modifiedHour > hour ? (p2 == 'am' ? 'pm' : 'am') : p2;
    return modifiedHour + ':' + minute + ' ' + am_pm;
  });
  $(this).text(modifiedText);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="body-time">8:00 pm - 9:00 pm</div>
<div class="body-time">10:30 pm - 11:00 pm</div>
<div class="body-time">8:00 pm - 10:30 pm</div>
<div class="body-time">11:00 pm - 1:00 am</div>
<div class="body-time">2:00 pm - 3:30 pm</div>
<div class="body-time">3:30 pm - 3:30 pm</div>
<div class="body-time">8:00 am - 9:00 am</div>
<div class="body-time">11:00 am - 11:30 am</div>
<div class="body-time">4:00 pm - 6:00 pm</div>
<div class="body-time">10:00 am - 10:30 am</div>