英文:
What RegEx would I use to parse sections of text?
问题
我试图编写一个将术语和定义的列表转换成闪卡的程序。我的想法是使用正则表达式来解析输入,如下所示:
term(1)-def(1)
term(2)-def(2)
term(3)-def(3)
term(4)-def(4)
term(5)-def(5)
解析为:
terms = ["term(1)","term(2)","term(3)","term(4)","term(5)"];
definitions = ["def(1)","def(2)","def(3)","def(4)","def(5)"];
我对正则表达式的语法非常陌生,所以不确定应该如何实现这个。
进一步的背景信息:
- 每行都包含这种格式:
term-definition\n - 我将在JavaScript中编写这个程序,以便将其托管在一个网站上(是的,我知道我不需要使用JS。这只是最简单的设置方式)。
 - 正则表达式应该仅避免第一个
-,因为在定义中可能会出现一个-。-绝不会出现在术语中。 
英文:
I'm attempting to write a program that converts lists of terms and definitions to flashcards. My though was to use RegEx to parse the input in the following way:
term(1)-def(1)
term(2)-def(2)
term(3)-def(3)
term(4)-def(4)
term(5)-def(5)
which parses to:
terms = ["term(1)","term(2)","term(3)","term(4)","term(5)"];
definitions = ["def(1)","def(2)","def(3)","def(4)","def(5)"];
I'm very new to RegEx syntax, so I'm not sure how exactly I would do this.
Further context:
- Each line contains this format: 
term-definition\n - I will be writing this in JavaScript so I can host the program on a website (yes, I am aware I don't need to use JS. It's just the simplest to get set up).
 - The RegEx should only avoid the first 
-, as one might appear in the definition.-will never appear in the term. 
答案1
得分: 0
你可以将第一个 - 之前的内容视为术语,将其后的内容视为定义:
const item = "term(1)-def(1)";
const rx = /([^-]+)-(.*)/;
const [, term, def] = rx.exec(item);
console.log(`term is "${term}"; def is "${def}"`);
但为什么不使用 JSON/对象来进行输入,以避免繁琐的字符串解析呢?不需要进行字符串解析。
const cards = [{
    term: "term 1",
    definition: "definition 1",
  },
  {
    term: "term 2",
    definition: "definition 2",
  },
  {
    term: "term 3",
    definition: "definition 3",
  }
];
const root = document.getElementById('root');
function makeElement(content, className, tag = 'div') {
  const el = document.createElement(tag);
  el.innerHTML = content;
  el.className = className;
  return el;
}
function appendCard(info, parent = root) {
  const card = makeElement('', 'card');
  const term = makeElement(info.term, 'term');
  const def = makeElement(info.definition, 'definition');
  card.appendChild(term);
  card.appendChild(def);
  parent.appendChild(card);
}
cards.forEach(item => appendCard(item));
:root {
  font-family: sans-serif;
}
#root {
  display: flex;
  gap: 1rem;
}
.card {
  background: aliceblue;
  flex: 0 0 150px;
  padding: 1rem;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.definition {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  background: skyblue;
}
.card:hover .definition {
  opacity: 1;
}
<p>鼠标悬停以显示定义</p>
<div id="root">
</div>
英文:
You could capture everything up to the first - as the term and everything that follows as the definition:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const item = "term(1)-def(1)";
const rx = /([^-]+)-(.*)/;
const [, term, def] = rx.exec(item);
console.log(`term is "${term}"; def is "${def}"`);
<!-- end snippet -->
But why not use JSON/objects for the input and save yourself all that pain? No string parsing necessary.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const cards = [{
    term: "term 1",
    definition: "definition 1",
  },
  {
    term: "term 2",
    definition: "definition 2",
  },
  {
    term: "term 3",
    definition: "definition 3",
  }
];
const root = document.getElementById('root');
function makeElement(content, className, tag = 'div') {
  const el = document.createElement(tag);
  el.innerHTML = content;
  el.className = className;
  return el;
}
function appendCard(info, parent = root) {
  const card = makeElement('', 'card');
  const term = makeElement(info.term, 'term');
  const def = makeElement(info.definition, 'definition');
  card.appendChild(term);
  card.appendChild(def);
  parent.appendChild(card);
}
cards.forEach(item => appendCard(item));
<!-- language: lang-css -->
:root {
  font-family: sans-serif;
}
#root {
  display: flex;
  gap: 1rem;
}
.card {
  background: aliceblue;
  flex: 0 0 150px;
  padding: 1rem;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.definition {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  background: skyblue;
}
.card:hover .definition {
  opacity: 1;
}
<!-- language: lang-html -->
<p>mouse over to reveal definition</p>
<div id="root">
</div>
<!-- end snippet -->
答案2
得分: 0
你可以使用此问题中描述的方法之一来拆分输入,然后将结果推送到 terms 和 definitions 数组,或者可能是一个定义对象:
const inp = `term 1 - definition 1
term 2 - definition 2 - contains a hyphen
term 3 - def 3
term 4 - has - lots - of - hyphens`
const terms = []
const definitions = []
const defobj = {}
inp.split('\n').forEach(line => {
  [term, definition, _] = line.split(/\s*-\s*(.*)/)
  terms.push(term)
  definitions.push(definition)
  defobj[term] = definition
})
console.log(terms)
console.log(definitions)
console.log(defobj)
英文:
You could split the input using one of the methods described in this question and then push the results to terms and definitions arrays or perhaps a definition object:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const inp = `term 1 - definition 1
term 2 - definition 2 - contains a hyphen
term 3 - def 3
term 4 - has - lots - of - hyphens`
const terms = []
const definitions = []
const defobj = {}
inp.split('\n').forEach(line => {
  [term, definition, _] = line.split(/\s*-\s*(.*)/)
  terms.push(term)
  definitions.push(definition)
  defobj[term] = definition
})
console.log(terms)
console.log(definitions)
console.log(defobj)
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论