-2

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.

2 Answers2

0

You could capture everything up to the first - as the term and everything that follows as the definition:

const item = "term(1)-def(1)";

const rx = /([^-]+)-(.*)/;

const [, term, def] = rx.exec(item);

console.log(`term is "${term}"; def is "${def}"`);

But why not use JSON/objects for the input and save yourself all that pain? No string parsing necessary.

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>mouse over to reveal definition</p>
<div id="root">
</div>
ray
  • 26,557
  • 5
  • 28
  • 27
  • Thanks, this is great. I forgot to properly specify, the idea is someone could drop in their list, and it would be converted automatically to save the trouble of converting to array by hand. –  Mar 06 '23 at 23:17
  • 1
    Answer updated with a regex solution. – ray Mar 06 '23 at 23:48
0

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:

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)
Nick
  • 138,499
  • 22
  • 57
  • 95