Copy link to clipboard
Copied
如何在Illustrator中执行通配符/ GREP / 正则表达式查找替换?- 平面设计堆栈交换
测试后,以下元字符未正确执行:^ $ /n (?<=) (?<!)(?=)(?!)
谁可以帮助我修改它
I tend to over-complicate things so you may want a simpler solution, but if I were to rewrite the function you've shown me I would do it like this:
var options = {
// Bypass all find/replace prompts, just remove the newlines:
removeNewlines: false,
//
find: {
value: "[\\r\\n\\cC]", // Text to appear as default
title: "Find:", // Title of window
desc: "Enter RegExp/GREP/Text", // Description of window
flags: "gm",
},
replace: {
value: "",
title: "Replace:",
...
Copy link to clipboard
Copied
After testing, the following metacharacters are not executed correctly: ^ $ /n (?<=) (?<!) (?=) (?!)
Who can help me modify it
Copy link to clipboard
Copied
Are you sure that ^, $, \n are not executed correctly? I've never noticed any issues there.
Negative and positive lookbehinds like (?<=) and (?<!) were not added to Javascript until much later than what is supported in Extendscript. You can often replicate them through lookaheads but that depends on the complexity of the expression.
Negative and positive lookaheads are supported:
// Positive lookahead:
var regex = /First(?= test)/g;
var test1 = 'First test'.match(regex),
test2 = 'First peach'.match(regex),
test3 = 'This is a First test in a year.'.match(regex),
test4 = 'This is a First peach in a month.'.match(regex)
alert(test1) // ['First'], correct
alert(test2) // null, correct
alert(test3) // ['First'], correct
alert(test4) // null, correct
// Negative lookahead:
var result = /\d+(?!\.)/g.exec('3.141');
alert(result) // '141', correct
alert(result.index) // 2, correct
alert(result.input) // '3.141', correct
May be a syntax error with your code?
Copy link to clipboard
Copied
please elaborate, what's the initial string and what's the result you're after?
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Solved: Find and change mutliple texts in illustrator and ... - Adobe Support Community - 10484449
ai_re/ai_re_v1.5.zxp at master · dumbm1/ai_re · GitHub
It can help me here, but it must select the text box. I want to find and replace without selecting the text
Copy link to clipboard
Copied
Isn't newline/linefeed character specific to OS? For instance on Windows, a normal press of Enter produces 003 shown on left with "Lorem ipsum dolor" and Control+Enter produces 015 shown on right with "hello world".
You can always identify a character via String.charCodeAt() to get the ASCII value to see exactly what character is being used for newlines (whether /r, /n, /r/n, or even ^z) then use caret syntax like above \c_ to target it.
Copy link to clipboard
Copied
thank you!
Although I don't understand JavaScript language, I learned it for two days. I understand your code, but I can't really modify it.
The following is the author's original code. Note that this is the grep script in illustrator.
How to do a wildcard / GREP / regex find-replace in Illustrator? - Graphic Design Stack Exchange
var scope = app.activeDocument.selection.length ? app.activeDocument.selection : app.activeDocument.pageItems; var find = prompt("Find: (Text or GREP/regex)",""); if(find !== null){ var replace = prompt("Replace: (Text or GREP/regex)",""); if(replace !== null){ var changes = 0; for(var i=0;i<scope.length;i++){ var text = scope[i]; var string = text.contents; if(typeof string == "string"){ var newstring = string.replace( new RegExp(find, 'g'), replace); if (newstring != string) { changes++; var paragraphsArray = newstring.split("\n"); text.paragraphs.removeAll(); for(var ii=0;ii<paragraphsArray.length;ii++){ text.paragraphs.add(paragraphsArray[ii]); } } } } alert( changes==1 ? "1 text object changed" : changes + " text objects changed"); } }
Copy link to clipboard
Copied
No worries. I'm not sure I understand though, you want to find and replace text and I understand that you want to find newlines but what are you trying to replace them with?
Copy link to clipboard
Copied
1. /n
I know this is not very important, but I want to fix them because sometimes I want to delete it.
2. ^、$
These two are very important to me. I think there is any way to achieve them, like the following.
Copy link to clipboard
Copied
I can't really speak to the accuracy of the CEP panel you're using, but if you wanted to delete newlines this could be done like so:
var find = /[\r\n\cC]/gm,
replace = " ";
var texts = app.activeDocument.textFrames;
for (var i = 0; i < texts.length; i++)
texts[i].contents = texts[i].contents.replace(find, replace);
With regards to ^, you can split the string, process each line, then join and replace it:
var find = /^./gm,
replace = "2"
var doc = app.activeDocument,
texts = doc.textFrames;
for (var i = 0; i < texts.length; i++) {
var content = texts[i].contents;
var lines = content.split(/[\r\n\cC]/gm),
newStr = []
for (var e = 0; e < lines.length; e++)
newStr.push(lines[e].replace(find, replace));
texts[i].contents = newStr.join("\r\n");
}
Before running we have two TextFrameItems, the one at the top has word-wrapping and no newline but the TextFrame at the bottom ("foo, test, hello") has two newlines:
With the result being:
Copy link to clipboard
Copied
Thank you. Have a nice weekend!
Your script is very good, but I want to implement this function based on this script. Is it feasible?
How to do a wildcard / GREP / regex find-replace in Illustrator? - Graphic Design Stack Exchange
Copy link to clipboard
Copied
I tend to over-complicate things so you may want a simpler solution, but if I were to rewrite the function you've shown me I would do it like this:
var options = {
// Bypass all find/replace prompts, just remove the newlines:
removeNewlines: false,
//
find: {
value: "[\\r\\n\\cC]", // Text to appear as default
title: "Find:", // Title of window
desc: "Enter RegExp/GREP/Text", // Description of window
flags: "gm",
},
replace: {
value: "",
title: "Replace:",
desc: "Enter Text",
},
confirm: {
value: false,
title: "Enable line-splitting?",
desc: "Choose no to enable global flags and newline targeting",
},
lineSplitting: {
onSplit: /[\r\n\cC]/gm, // RegExp to use for manual newline split
onJoin: "\r\n", // Value to join newlines back with
},
showChanges: true, // Whether to display alert on completion noting change count
};
Array.prototype.filter = function(callback) {
var filtered = [];
for (var i = 0; i < this.length; i++)
if (callback(this[i], i, this)) filtered.push(this[i]);
return filtered;
};
function get(type, parent) {
if (arguments.length == 1 || !parent) parent = app.activeDocument;
var result = [];
if (!parent[type]) return result;
for (var i = 0; i < parent[type].length; i++) result.push(parent[type][i]);
return result;
}
function findReplace() {
try {
var doc = app.activeDocument,
scope = doc.selection.length
? get("selection").filter(function(i) {
return i.typename == "TextFrame";
})
: doc.textFrames,
count = 0;
if (options.removeNewlines) {
for (var i = 0; i < scope.length; i++) {
var content = scope[i].contents;
var lines = content.split(/[\r\n\cC]/gm),
newStr = [];
for (var e = 0; e < lines.length; e++)
newStr.push(lines[e].replace(find, replace));
scope[i].contents = newStr.join(" ").replace(/\s{2,}/gm, "");
}
return null;
}
var find = prompt(
options.find.desc,
options.find.value,
options.find.title
);
if (find !== null) {
var findRX = new RegExp(find, options.find.flags),
shouldSplit = confirm(
options.confirm.desc,
!options.confirm.value,
options.confirm.title
);
var replace = prompt(
options.replace.desc,
options.replace.value,
options.replace.title
);
if (replace !== null) {
for (var i = 0; i < scope.length; i++) {
var content = scope[i].contents;
if (shouldSplit) {
var lines = content.split(options.lineSplitting.onSplit),
newStr = [];
for (var e = 0; e < lines.length; e++) {
if (findRX.test(lines[e])) count++;
newStr.push(lines[e].replace(findRX, replace));
}
scope[i].contents = newStr.join(options.lineSplitting.onJoin);
} else {
if (findRX.test(scope[i].contents)) count++;
scope[i].contents = scope[i].contents.replace(findRX, replace);
}
}
if (options.showChanges) {
var alertStr = !count
? "No changes made"
: count > 1
? count + " changes made"
: "1 change made";
alert(alertStr);
}
}
}
} catch (err) {
alert("Error: " + err);
}
}
findReplace();
With options.removeNewLines set, there is no UI. It just takes this:
And turns it into this:
Otherwise all the option values at the top of the script determine the behavior and UI:
The above defaults to No, which targets the "paragraph" and all lines for a single RegExp replace. When choosing Yes, it will split each line into a sentence and run an individual replace on each sentence, then reconstruct and assign the value back to the original TextFrame. All this behavior is configurable through the options object at the top of the script.
Copy link to clipboard
Copied
Thank you! Your script solved all my problems perfectly.