1

I am using Javascript to manipulate items in ZOTERO.

I have multiple items whose title contains " : " (a colon between spaces).

I want to replace this with ", " (a comma and a space).

For example:

This is : an example

should be

This is, an example

Can anyone tell me if the .replace statement in my code is correct?

var fieldName = "title";
 
var fieldID = Zotero.ItemFields.getID(fieldName);
var s = new Zotero.Search();
s.libraryID = ZoteroPane.getSelectedLibraryID();
s.addCondition(fieldName, 'contains', '  ');
var ids = await s.search();
if (!ids.length) {
    return "No items found";
}
await Zotero.DB.executeTransaction(async function () {
    for (let id of ids) {
        let item = await Zotero.Items.getAsync(id);
        let mappedFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(item.itemTypeID, fieldName);
        let fieldID = mappedFieldID || fieldID;
        item.setField(fieldID, item.getField(fieldID).replace(/[\s:\s]/g, ', '));
        await item.save({
            skipDateModifiedUpdate: true
        });
    }
});
return ids.length + " item(s) updated";
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
OnceUponATime
  • 450
  • 4
  • 12
  • 2
    `[\s:\s]` is whitespace or `:`. You'd want `\s[:]\s` or probably more likely space:space (SO won't format spaces in code blocks correctly). `\s` is any white space, not just a space. – user3783243 Mar 08 '21 at 17:49
  • Looks fine at first glance; did you test this? Are you encountering errors? Unexpected results? Please clarify the issue you have. –  Mar 08 '21 at 17:50
  • 1
    https://regexper.com/#%2F%5B%5Cs%3A%5Cs%5D%2Fg – epascarello Mar 08 '21 at 17:55
  • No, I did not test my script yet because I will be changing hundreds of items and would like to avoid setting the whole DB back to the latest backup. If I understood @user3783243 correctly, [\s:\s] would replace any colon with a comma, not just colons between spaces? – OnceUponATime Mar 08 '21 at 17:59
  • Correct, any colon or space. https://regex101.com/r/mjVNIM/1/ – user3783243 Mar 08 '21 at 20:48

1 Answers1

5

String.prototype.replaceAll() should work just fine in this case

const test = 'This is : an example'
console.log(test.replaceAll(' : ', ', '));

Note IE does not support this JavaScript built-in: Can I use...

As an alternative, you can use a global //g regex:

const test = 'This is : an example'
console.log(test.replace(/\ :\ /g, ', '));
0stone0
  • 34,288
  • 4
  • 39
  • 64
  • 1
    Good answer: no regex needed! – Nir Alfasi Mar 08 '21 at 17:52
  • 1
    You can also use `String.split(' : ')` and `Array.join(', ')`. Not the best way to solve this problem, but its still a useful tool in some other situations if you don't know about it! – cseitz Mar 08 '21 at 17:52
  • This looks straightforward, but not sure this is supported in ZOTERO. I am using the in-built "Run JavaScript" console: https://www.zotero.org/support/dev/client_coding/javascript_api – OnceUponATime Mar 08 '21 at 18:02
  • There is no need to escape the spaces in the regex, `/ : /g` works fine. Escaping spaces is only needed when "[free-spacing](http://www.rexegg.com/regex-modifiers.html#freespacing)" mode (`x` flag) is active (not supported in JavaScript). – 3limin4t0r Mar 08 '21 at 18:17
  • `.replaceAll` produced an error, so I will try regex again: `TypeError: item.getField(...).replaceAll is not a function` – OnceUponATime Mar 08 '21 at 18:24