1

Probably extremely obvious but I don't really get along with regex...

I am trying to extract the font name from a sass file containing a @font-face in javascript. The example would be the following:

Given this string:

@font-face {
    font-family: 'fancy-icons';
    src:
        url('#{$icon-font-path}/fancy-icons.ttf?p3owtd') format('truetype'),
        url('#{$icon-font-path}/fancy-icons.woff?p3owtd') format('woff'),
        url('#{$icon-font-path}/fancy-icons.svg?p3owtd#fancy-icons') format('svg');
    font-weight: normal;
    font-style: normal;
}

I want to extract the word fancy-icons, meaning the string within the single quotes and it could be anything.

The closes attempt led me to this code:

const scssContent = fs.readFileSync(path.resolve('fonts.scss'), 'utf-8');
scssContent.match(new RegExp(/font-family: '(.*?)';/g));

but all I am getting is the whole font-family: 'fancy-icons';.

Thanks in advance.

nass600
  • 599
  • 2
  • 11
  • 22
  • 1
    Possible duplicate of [How do you access the matched groups in a JavaScript regular expression?](https://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression) – ctwheels Nov 27 '17 at 18:57
  • 1
    Your regex is fine. You just need to access the proper capture group. I'd suggest using `font-family:\s*'([^']*)'` instead, but your regex is still fine. – ctwheels Nov 27 '17 at 18:58
  • Forgot to say `font-family: 'fancy-icons';` is the only matching group I am getting – nass600 Nov 27 '17 at 19:07

2 Answers2

2

Brief

As I mentioned in the comments below your question, you simply need to access the first capture group. I'm not sure what code you're using in JavaScript, but below is a snippet that performs the suggested edit I made as well as some minor adjustments to your regex to improve performance (using [^']* instead of .*?).


Code

See regex in use here

font-family:\s*'([^']*)'

Usage

var s = `@font-face {
    font-family: 'fancy-icons';
    src:
        url('#{$icon-font-path}/fancy-icons.ttf?p3owtd') format('truetype'),
        url('#{$icon-font-path}/fancy-icons.woff?p3owtd') format('woff'),
        url('#{$icon-font-path}/fancy-icons.svg?p3owtd#fancy-icons') format('svg');
    font-weight: normal;
    font-style: normal;
}`;

var r = /font-family:\s*'([^']*)'/g;
var m = r.exec(s);
while(m != null) {
  console.log(m[1]);
  m = r.exec(s);
}

Explanation

  • font-family: Match this literally
  • \s* Match any number of whitespace characters
  • ' Match the apostrophe character literally
  • ([^']*) Capture any character except the apostrophe character any number of times into capture group 1
  • ' Match the apostrophe character literally
ctwheels
  • 21,901
  • 9
  • 42
  • 77
  • Don't ask me why but it wasn't working with `match` on the sass string read from the file with node. Thanks!! – nass600 Nov 27 '17 at 19:27
1

You can do something like that:

const arr = [
  `font-family:'xxx';`,
  `font-family:'xxx'`,
  `font-family: 'xxx';`,
  `font-family: "xxx";`,
  `font-family:"xxx";`
];

arr.forEach(str => console.log(str.match(/font\-family:\s*['"]([^"']+)['"];?/)))
felixmosh
  • 32,615
  • 9
  • 69
  • 88