首页 > 解决方案 > 正则表达式从长字符串中提取日期范围

问题描述

这是整个字符串

Now that your RV has been booked, we will deposit $152.00 into your account 24 hours after #### picks up your RV.
We will also hold the $500.00 security deposit to cover any unforseen costs.

Booking Details
Tab Teardrop - Hip Modern Travel Trailer
Trailer - Sleeps 2
Friday, July 31, 2020 - Sunday, August 2, 2020

Pickup Details
Friday, July 31, 2020

我只想使用正则表达式提取这部分。

Tab Teardrop - Hip Modern Travel Trailer
Trailer - Sleeps 2
Friday, July 31, 2020 - Sunday, August 2, 2020

标签: javascriptregex

解决方案


有时你只需要编写自己的解析器。

正则表达式对于此任务来说太复杂了。

const originalText = document.querySelector('.hidden').value.trim();

const parseInvoice = (input, target) => {
  const lines = input.split('\n'), buffer = [];
  let isActive = false, line;
  for (let i = 0; i < lines.length; i++) {
    line = lines[i];
    if (line === target) {
      isActive = true;
      continue;
    }
    if (isActive && line.trim().length === 0) {
      break;
    }
    if (isActive) {
      buffer.push(line);
    }
  }
  return buffer.join('\n');
};

console.log(parseInvoice(originalText, 'Booking Details'));
.hidden { display: none; }
.as-console-wrapper { top: 0; max-height: 100% !important; }
<textarea class="hidden">
Now that your RV has been booked, we will deposit $152.00 into your account 24 hours after #### picks up your RV.
We will also hold the $500.00 security deposit to cover any unforeseen costs.

Booking Details
Tab Teardrop - Hip Modern Travel Trailer
Trailer - Sleeps 2
Friday, July 31, 2020 - Sunday, August 2, 2020

Pickup Details
Friday, July 31, 2020
</textarea>

您可以将表达式简化为此。

const parseInvoice = (input, target) => {
  let isActive = false;
  return input.split('\n').filter(line => {
    if (line === target) { isActive = true; return false; }
    if (isActive && line.trim().length === 0) { isActive = false; return false; }
    return isActive;
  }).join('\n');
};

如果您只想扫描到第一个空行,则需要另一个标志,但请记住,过滤器将扫描每一行。如果您只想扫描最少的行数,您应该使用Array.prototype.someor Array.prototype.every

const parseInvoice = (input, target) => {
  let isActive = false, done = false;
  return input.split('\n').filter(line => {
    if (done) return false;
    if (line === target) {
      isActive = true; return false;
    }
    if (isActive && line.trim().length === 0) {
      isActive = false; done = true; return false;
    }
    return isActive;
  }).join('\n');
};

如果要使用正则表达式进行匹配,可以修改函数以获取开始和结束表达式。有很多方法可以实现这一点。由您决定。

const parseInvoice = (input, startExpr, endExpr, keepMatches) => {
  const lines = input.split('\n'), buffer = [];
  let isActive = false, line;
  for (let i = 0; i < lines.length; i++) {
    line = lines[i];
    if (line.match(startExpr)) {
      isActive = true;
      if (keepMatches) buffer.push(line);
      continue;
    }
    if (isActive && line.match(endExpr)) {
      if (keepMatches) buffer.push(line);
      break;
    }
    if (isActive) {
      buffer.push(line);
    }
  }
  return buffer.join('\n');
};

console.log(parseInvoice(originalText, /^Booking Details$/, /^$/, true));

推荐阅读