Is it possible to add whitespace without introducing word boundaries?

As an example, consider the following snippet:

#let format-number(num) = {
    num.split("_").join(sym.space.thin)
}

#format-number("1_234_567_890")

that groups digits of a large number to make it easier to read. When I copy & paste the text from the generated PDF, it will include the spaces, however. (That is, "1 234 567 890"). Using h(0.2em) instead of sym.space.thin gives the same result.

Is there a way to achieve the same visual appearance, while ensuring that the result of copying from the PDF is "1234567890"?

zero also inserts a space, but after trying using text.tracking, it appears that any visual spacing is considered by a PDF viewer as a space. So the only thing that worked is using 0.14 em or less.

text.tracking
#let format-number(num, group-spacing: 0.2em) = {
  let parts = num
    .split("_")
    .map(part => {
      let clusters = part.clusters()
      if clusters.len() == 1 {
        (part, none, none)
      } else if clusters.len() == 2 {
        let (first, last) = clusters
        (first, none, last)
      } else {
        let (first, ..middle, last) = clusters
        (first, middle.join(), last)
      }
    })
  let previous-last
  let with-spacing(a, b) = text(tracking: group-spacing, a + b)
  for (i, (first, middle, last)) in parts.enumerate() {
    if last == none and middle == none {
      if i + 1 == parts.len() {
        with-spacing(previous-last, first)
      }
      previous-last = first
    } else if last == none and middle != none {
      with-spacing(previous-last, first)
      if i + 1 == parts.len() { middle }
      previous-last = middle
    } else {
      with-spacing(previous-last, first)
      middle
      if i + 1 == parts.len() { last }
      previous-last = last
    }
  }
}
#format-number("1_234_567_890")

#let format-number(num, group-spacing: 0.2em) = {
  let parts = num
    .text
    .split()
    .map(part => {
      let clusters = part.clusters()
      if clusters.len() == 1 {
        (part, none, none)
      } else if clusters.len() == 2 {
        let (first, last) = clusters
        (first, none, last)
      } else {
        let (first, ..middle, last) = clusters
        (first, middle.join(), last)
      }
    })
  let previous-last
  for (i, (first, middle, last)) in parts.enumerate() {
    if last == none and middle == none {
      if i + 1 == parts.len() {
        text(tracking: group-spacing, previous-last + first)
      }
      previous-last = first
    } else if last == none and middle != none {
      text(tracking: group-spacing, previous-last + first)
      if i + 1 == parts.len() { middle }
      previous-last = middle
    } else {
      text(tracking: group-spacing, previous-last + first)
      middle
      if i + 1 == parts.len() { last }
      previous-last = last
    }
  }
}
#format-number[1 234 567 890]

#let format-number(num, group-spacing: 0.2em) = {
  let parts = num
    .text
    .clusters()
    .rev()
    .chunks(3)
    .map(array.rev)
    .rev()
    .map(clusters => {
      if clusters.len() == 1 {
        (..clusters, none, none)
      } else if clusters.len() == 2 {
        let (first, last) = clusters
        (first, none, last)
      } else {
        let (first, ..middle, last) = clusters
        (first, middle.join(), last)
      }
    })
  let previous-last
  for (i, (first, middle, last)) in parts.enumerate() {
    if last == none and middle == none {
      if i + 1 == parts.len() {
        text(tracking: group-spacing, previous-last + first)
      }
      previous-last = first
    } else if last == none and middle != none {
      text(tracking: group-spacing, previous-last + first)
      if i + 1 == parts.len() { middle }
      previous-last = middle
    } else {
      text(tracking: group-spacing, previous-last + first)
      middle
      if i + 1 == parts.len() { last }
      previous-last = last
    }
  }
}
#format-number[1234567890]

I also tried but haven’t succeeded so far.

Even with manual placement of the number segments, there appears to be an automatic space in PDFs for anything which appears wider than 0.1499em:

#let format-number(num) = context {
	let number = num.split("_")
	let widths = number.map(seg => (measure(seg).width, measure(sym.space.fig).width))
	for (i, num) in number.enumerate() { place(dx: widths.slice(0, i).flatten().sum(default: 0pt), num) }
}

1#sym.space.fig;234#sym.space.fig;567#sym.space.fig;890

#format-number("1_234_567_890")

Both of these numbers copy the same way.